2

我正在实现一个通过 JSON-RPC 协议与 iframe 通信的小书签。

然而,一些网站,例如 cnn.com 会加载 JSON2,window.JSON尽管浏览器已经有一个原生的 JSON 对象。

问题是,在我的 iframe 中,我不想遵循同样的错误做法,而且 JSON2 似乎与 Mozilla Firefox 和 Chrome 上的本机 JSON 不兼容:

因此,当我在本机 JSON 和 JSON2 上运行 stringify 时,我得到以下结果:

JSON.stringify({key: "value"})

JSON2

{key:"value"}

原生 JSON

{"key":"value"}

(密钥包含在 中"


"问题是,当JSON2 生成的字符串中缺少 并引发错误时,本机 JSON 不喜欢它:

火狐浏览器:SyntaxError: JSON.parse: expected property name or '}'

谷歌浏览器:SyntaxError: Unexpected token k

为了彻底解决这个问题,我需要确保使用与解码字符串相同的 JSON 库来编码字符串。

一种方法是确保在双方都使用 JSON2 或 JSON3,但我想尽可能使用本机 json 库。

所以现在像 cnn.com 这样的网站已经覆盖了原生 JSON 库,我怎样才能回到它呢?

我也许可以创建一个指向同一个域的 iframe 并从中获取 JSON 对象contentWindow,但这会非常低效。

没有更好的方法吗?

4

2 回答 2

2

不确定我是否正确理解您的问题

如果你像这样放置一个空的 iframe

<iframe id="testFrame" name="testFrame" src="about:blank" style="display:none;"></iframe>

那么你也可以从js调用

testFrame.JSON.stringify(obj);

唯一的问题是如果你在https:src 中使用它可能是javascript:false你需要支持 IE6

编辑:我仍然认为我不值得被接受的答案,所以我想出了你的代码的修改版本

(function($) {
  var frm;
  $.getNative = function(objectName, callback) {
    if (!frm) {
      frm= $("<iframe>", {
        src: "javascript:false",
        style: "display:none;"
      }).appendTo("body").load(function(){
        callback(this.contentWindow[objectName]);
        // $(this).remove(); <-- this is commented to cache the iframe
      });
    }
    callback(frm[0].contentWindow[objectName]);
  }
})(jQuery)

这将使您能够$.getNative()在文档中多次使用,而无需每次都重新创建框架。

于 2012-10-12T21:07:41.963 回答
0

到目前为止,最好的解决方案是使用 iframe,但正如 Crisim Il Numenoreano 指出的那样,它应该指向about:blankor javascript:false。到目前为止,这似乎工作正常:

function getNative(objectName, callback) {
    $("<iframe>", {
        src: "javascript:false",
        style: "display:none;"
    }).appendTo("body").load(function(){
        callback(this.contentWindow[objectName]);
        $(this).remove();
    });
}

//Use like this:

getNative("JSON", function(JSON) {
    console.log(JSON.stringify({key: "value"}));
});

请注意,对于小书签,jquery 必须从可靠的来源获取并在本地范围内进行保护。

于 2012-10-12T22:21:00.723 回答