简体   繁体   English

PrototypeJS版本1.6.0.2重写JSON.parse和JSON.stringify并中断socket.io功能

[英]PrototypeJS version 1.6.0.2 Overrides JSON.parse and JSON.stringify and breaks socket.io functionality

Basically, socket.io uses nativeJSON to enconde and decode packets, and my problem is that I am obliged to use this version of prototype which changes JSON behaviour. 基本上,socket.io使用nativeJSON来包含和解码数据包,我的问题是我不得不使用这个版本的原型来改变JSON行为。 When I should get in the server something like: 什么时候我应该进入服务器,如:

socket.on('event', function (a, b, c) , I get socket.on('event', function ([a, b, c], undefined, undefined) . socket.on('event', function (a, b, c) ,我得到socket.on('event', function ([a, b, c], undefined, undefined)

One solution is to comment this lines on json.js: 一种解决方案是在json.js上注释这一行:

/* socket.io-client/lib/json.js
if (nativeJSON && nativeJSON.parse){
    return exports.JSON = {
      parse: nativeJSON.parse
    , stringify: nativeJSON.stringify
    };
  }
*/

but this change affects performance seriously. 但这种变化严重影响了业绩。

Is there a way to recover native JSON functionality? 有没有办法恢复原生JSON功能? Would it be possible to create a hidden iframe just to clone the JSON object to restore the old functionality? 是否可以创建一个隐藏的iframe来克隆JSON对象以恢复旧功能?

One solution is to kill Prototype's toJSON() extension methods: 一种解决方案是杀死Prototype的toJSON()扩展方法:

if(window.Prototype) {
    delete Object.prototype.toJSON;
    delete Array.prototype.toJSON;
    delete Hash.prototype.toJSON;
    delete String.prototype.toJSON;
}

Then you should be able to use the browser's native JSON.parse/stringify methods without issue. 然后你应该能够毫无问题地使用浏览器的原生JSON.parse / stringify方法。

If you don't want to kill everything, and have a code that would be okay on most browsers, you could do it this way : 如果您不想杀死所有内容,并且拥有可在大多数浏览器上使用的代码,您可以这样做:

(function (undefined) { // This is just to limit _json_stringify to this scope and to redefine undefined in case it was
  if (true ||typeof (Prototype) !== 'undefined') {
    // First, ensure we can access the prototype of an object.
    // See http://stackoverflow.com/questions/7662147/how-to-access-object-prototype-in-javascript
    if(typeof (Object.getPrototypeOf) === 'undefined') {
      if(({}).__proto__ === Object.prototype && ([]).__proto__ === Array.prototype) {
        Object.getPrototypeOf = function getPrototypeOf (object) {
          return object.__proto__;
        };
      } else {
        Object.getPrototypeOf = function getPrototypeOf (object) {
          // May break if the constructor has been changed or removed
          return object.constructor ? object.constructor.prototype : undefined;
        }
      }
    }

    var _json_stringify = JSON.stringify; // We save the actual JSON.stringify
    JSON.stringify = function stringify (obj) {
      var obj_prototype = Object.getPrototypeOf(obj),
          old_json = obj_prototype.toJSON, // We save the toJSON of the object
          res = null;
      if (old_json) { // If toJSON exists on the object
        obj_prototype.toJSON = undefined;
      }
      res = _json_stringify.apply(this, arguments);
      if (old_json)
        obj_prototype.toJSON = old_json;
      return res;
    };
  }
}.call(this));

This seems complex, but this is complex only to handle most use cases. 这似乎很复杂,但这只是处理大多数用例的复杂问题。 The main idea is overriding JSON.stringify to remove toJSON from the object passed as an argument, then call the old JSON.stringify , and finally restore it. 主要思想是重写JSON.stringify以从作为参数传递的对象中删除toJSON ,然后调用旧的JSON.stringify ,最后恢复它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM