【问题标题】:Access native JSON object when JSON2 has overloaded it当 JSON2 重载时访问本机 JSON 对象
【发布时间】:2012-10-03 16:35:55
【问题描述】:

我正在实现一个书签,它通过 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 不喜欢它:

Mozilla Firefox:SyntaxError: JSON.parse: expected property name or '}'

谷歌浏览器:SyntaxError: Unexpected token k

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

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

既然像 cnn.com 这样的网站已经覆盖了原生 JSON 库,我该如何恢复呢?

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

没有更好的办法吗?

【问题讨论】:

  • json2 do 用双引号将密钥完全包裹起来......
  • @CrisimIlNumenoreano 不是 CNN 安装的任何版本。

标签: javascript json dom cross-domain bookmarklet


【解决方案1】:

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

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

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

那么你也可以从js调用

testFrame.JSON.stringify(obj);

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

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

(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(),而无需每次都重新创建框架。

【讨论】:

  • 提问者提到了这个技巧,但希望避免动态创建 iframe。唉,我找不到其他解决方案,所以这可能是要采取的方法。
  • @LukeDennis 对不起,我帮不上忙 :(
  • 没有意识到 about:blankjavascript:false 会像跨域一样工作。所以这是一个改进,因为它不需要像我最初打算的那样点击window.location.href...+1
  • 伙计们,也许你知道为什么返回值可以是未定义的问题的答案?我在这里问这个:stackoverflow.com/questions/37209246/…
【解决方案2】:

到目前为止,最好的解决方案是使用 iframe,但正如 Crisim Il Numenoreano 所指出的,它应该指向 about:blankjavascript: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 必须从可靠来源获取并在本地范围内进行保护。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-13
    • 1970-01-01
    • 2020-10-25
    • 2017-07-05
    • 2021-11-07
    • 2021-12-08
    相关资源
    最近更新 更多