如何扩展EJSON以序列化RegEx以进行Meteor客户端 - 服务器交互?

时间:2016-02-22 09:00:26

标签: javascript json regex meteor coffeescript

我有一个任意的(E)JSON,它可以在我的Meteor应用程序中通过网络从客户端发送到服务器。它使用RegExp个对象来对结果进行归零:

# on the client
selector = 
  "roles.user": { "$ne": null } 
  "profile.email": /^admin@/gi 

所有在客户端都很好,但是如果我通过Meteor.callMeteor.subscribe将其传递给服务器,则生成的(E)JSON采用以下形式:

# on the server
selector =
  "roles.user": { "$ne": null }
  "profile.email": {}

......而某个工程师在内部死了一点。

Web上有大量资源,通过JSON.stringify / JSON.parse或等效的EJSON方法解释RegEx无法序列化的原因。

我不相信RegEx序列化是不可能的。那怎么办呢?

2 个答案:

答案 0 :(得分:6)

在审核this HowTothe Meteor EJSON Docs后,我们可能会使用EJSON.addType方法序列化RegEx。

扩展RegExp - 为RegExp提供实现所需的方法{.1}}。

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() } 中定义的对象。

toJSONValue

在您的控制台中测试 - 请不要相信我的话。亲眼看看。

EJSON.addType "RegExp", (value) ->
  return new RegExp(value['regex'], value['options'])

你有一个RegExp在客户端和服务器上被序列化和解析,能够通过线路传递,保存在Session中,甚至可能存储在查询集合中!

编辑加入IE10 +错误:在严格模式下不允许分配给只读属性由@Tim Fletcher在评论中提供

> o = EJSON.stringify(/^Mooo/ig)
"{"$type":"RegExp","$value":{"regex":"^Mooo","options":"ig"}}"
> EJSON.parse(o)
/^Mooo/gi

答案 1 :(得分:0)

有一个更简单的解决方案: 通过.toString()对您的RegExp进行字符串化,将其发送到服务器,然后再将其解析回RegExp。