如何扩展 EJSON 以序列化 Meteor 客户端-服务器交互的 RegEx
How to extend EJSON to serialize RegEx for Meteor Client-Server interactions?
我有一个任意的(E)JSON,它是在我的Meteor应用程序中通过线路从客户端发送到服务器的。它使用RegExp
对象来归零结果:
# on the client
selector =
"roles.user": { "$ne": null }
"profile.email": /^admin@/gi
在客户端一切都很好,但是如果我通过Meteor.call
或Meteor.subscribe
将其传递给服务器,则生成的(E)JSON采用以下形式:
# on the server
selector =
"roles.user": { "$ne": null }
"profile.email": {}
。在某个地方,工程师在内部死了一点。
网络上有很多资源解释了为什么正则表达式无法通过JSON.stringify
/JSON.parse
或等效的EJSON
方法进行序列化。
我不相信正则表达式序列化是不可能的。那么如何才能做到呢?
在查看了本操作方法和 Meteor EJSON 文档之后,我们可以使用 EJSON.addType
方法序列化正则表达式。
扩展正则表达式 - 为正则表达式提供实施所需的EJSON.addType
方法。
RegExp::options = ->
opts = []
opts.push 'g' if @global
opts.push 'i' if @ignoreCase
opts.push 'm' if @multiline
return opts.join('')
RegExp::clone = ->
self = @
return new RegExp(self.source, self.options())
RegExp::equals = (other) ->
self = @
if other isnt instanceOf RegExp
return false
return EJSON.stringify(self) is EJSON.stringify(other)
RegExp::typeName = ->
return "RegExp"
RegExp::toJSONValue = ->
self = @
return {
'regex': self.source
'options': self.options()
}
调用 EJSON.addType - 在任何地方执行此操作。不过,最好将其提供给客户端和服务器。这将反序列化上面toJSONValue
中定义的对象。
EJSON.addType "RegExp", (value) ->
return new RegExp(value['regex'], value['options'])
在您的控制台中测试 - 不要相信我的话。你自己看吧。
> o = EJSON.stringify(/^Mooo/ig)
"{"$type":"RegExp","$value":{"regex":"^Mooo","options":"ig"}}"
> EJSON.parse(o)
/^Mooo/gi
在那里,您可以在客户端和服务器上序列化和解析一个 RegExp,能够通过网络传入,保存在会话中,甚至可能存储在查询集合中!
编辑以添加 IE10+ 错误:在严格模式下不允许分配给只读属性 由@Tim Fletcher在评论中提供
import { EJSON } from 'meteor/ejson';
function getOptions(self) {
const opts = [];
if (self.global) opts.push('g');
if (self.ignoreCase) opts.push('i');
if (self.multiline) opts.push('m');
return opts.join('');
}
RegExp.prototype.clone = function clone() {
return new RegExp(this.source, getOptions(this));
};
RegExp.prototype.equals = function equals(other) {
if (!(other instanceof RegExp)) return false;
return EJSON.stringify(this) === EJSON.stringify(other);
};
RegExp.prototype.typeName = function typeName() {
return 'RegExp';
};
RegExp.prototype.toJSONValue = function toJSONValue() {
return { regex: this.source, options: getOptions(this) };
};
EJSON.addType('RegExp', value => new RegExp(value.regex, value.options));
有一个更简单的解决方案:通过.toString()
字符串化您的正则表达式,将其发送到服务器,然后将其解析回正则表达式。
相关文章:
- Meteor方法在客户端返回null,在客户端运行的相同方法返回正确的值
- Meteor:在启动时将html注入客户端文件
- 服务器上的Meteor客户端断开连接事件
- 从客户端更新Meteor.users
- Meteor针对唯一客户端集合的发布/订阅策略
- 服务器上的 Meteor.publish 不会在客户端上显示新文档
- 如何将错误消息从 meteor 服务器传递到客户端
- 为什么自定义 JavaScript 文件放在客户端文件夹中时不在我的 Meteor 模板上呈现
- Meteor:使用HTTP.get从客户端访问网站(CORS错误)
- Meteor 方法返回客户端和服务器上的不同对象
- Meteor集合在服务器和客户端上有所不同
- 调试器在Meteor.call(可能是客户端/服务器调试)之后停止
- 仅当客户端连接到Meteor服务器时才运行代码
- 假设:Meteor.call()首先尝试在客户端环境中运行,这是真的吗
- 如何重新运行Meteor出版物以刷新客户端上收藏的内容
- 客户端上的Meteor.js集合为空
- Meteor脚本确保在其他一切之前执行(在客户端上)
- Meteor 方法返回未定义到客户端(异步)
- Meteor - 在客户端上的异步回调的 for 循环后运行代码
- Meteor 中的客户端渲染和光纤的性能影响