【问题标题】:"not well-formed" error in Firefox when loading JSON file with XMLHttpRequest使用 XMLHttpRequest 加载 JSON 文件时,Firefox 出现“格式不正确”错误
【发布时间】:2010-10-15 05:48:28
【问题描述】:

当我页面上的 JavaScript 加载包含 JavaScript Object Notation 格式的对象的文本文件时,我在 Firefox 3.0.7 的错误控制台中收到“格式不正确”错误。如果文件只包含 JSON 对象,则会产生错误。如果我将对象包装在 标记中,则不会产生错误。无论哪种方式,请求都会成功,所以我可以忽略它,但我不希望我的错误日志填满这些消息。

这里有一些示例代码来说明问题。首先,名为“data.json”的“格式不正确”的文件:

{ a: 3 }

现在一些代码来加载文件:

var req = new XMLHttpRequest();
req.open("GET", "data.json");
req.send(null);

这会在 Firefox 错误控制台中产生以下错误:

格式不正确
file://path/to/data.json 行:1
{一:3}
- ^

如果data.json修改成这样:

<document>{ a: 3 }</document>

没有错误。我认为它在抱怨是因为纯 JSON 文件不是格式良好的 XML 文档,所以我尝试在“发送”调用之前覆盖 MIME 类型以强制它作为纯文本加载,但这不起作用。

var req = new XMLHttpRequest();
req.open("GET", "data.json");
req.overrideMimeType("text/plain");
req.send(null);
// Still produces an error!

我将继续将我的 JSON 数据包装在一个 XML 文档中,以绕过 XMLHttpRequest 正在执行的任何验证,但我想知道是否有任何方法可以强制它不加批判地加载纯文本并且不要试图验证它。或者,除了 XMLHttpRequest 之外,还有其他可以与纯文本一起使用的数据加载方法吗?

【问题讨论】:

    标签: javascript firefox xmlhttprequest mime-types


    【解决方案1】:

    您是否尝试过对 JSON 使用 MIME 类型?

    application/json
    

    您还可以将服务器配置为自动为 .json 文件发送此 MIME 类型。

    【讨论】:

    • 更具体地说:req.overrideMimeType("application/json"); req.send(null);作品。在服务器中指定 MIME 类型会是更好的解决方案,但覆盖它也可以。
    • 这个应该放在哪里?在 JSON 文件中?
    • 本地开发有没有这样的方案?
    【解决方案2】:

    首先,真正的 JSON 比 JavaScript 严格得多,要成为有效的 JSON,您必须引用您的密钥。

     { "a": 3 } 
    

    此外,由于您使用的是纯 XMLHttpRequest,它通常期望接收 XML 结果,除非 MIME 标头另有严格规定。

    然而,您可能希望通过简单地使用 JavaScript 框架(例如 jQuery)来简化自己的生活,该框架将为您抽象出所有这些问题并处理所有令人讨厌的边缘情况。

    $.getJSON("data.json",{}, function( data ){ 
      /*  # do stuff here  */ 
    });
    

    此外,如果您同时使用严格的 JSON 并使用库为您抽象它,当浏览器开始使用原生 JSON 解析器时,该库将能够透明地使用这些解析器并获得显着的速度提升。

    (这迟早会发生,当它发生时,您的用户将获得无声升级!)。

    【讨论】:

    • 感谢 JSON 的指点。我将更改我的数据以使用带引号的字符串属性名称。不幸的是,jQuery 或其他一些框架对我来说不是一个选择。
    • 我最感兴趣的是为什么,通常这是强烈避免代码重用和避免使用已解决问题的代码臭味的标志。
    • @Kent,我很乐意使用 jQuery。然而,使用 jQuery 的审批过程非常困难。与客户争论并证明我们需要使用 jQuery 所花费的时间是不值得的。悲伤,但真实。
    • @A. Levy:你会学到东西,下次你就不太可能手动编写所有代码了:)
    • 使用$.getJSON() 仍然会为我生成该错误消息。
    【解决方案3】:

    实际上应该是 {"a": 3}。

    【讨论】:

      【解决方案4】:

      当 Content-Type 完全为空时也会发生这种情况(从而绕过自然类型检测)。

      【讨论】:

        【解决方案5】:

        肯特,我不同意。

        以下“有效”JSON:

        { a: 3 }
        

        JavaScript 对象属性名称不必是字符串。

        问题是 MIME 类型之一,而不是 JSON/JavaScript 语法。

        我刚刚通过将 json 作为“text/javascript”添加到我的网络服务器 mime 类型文件中解决了这个问题:

        text/javascript                 js, json
        

        “格式不正确”的错误消失了。浏览器 (FireFox) 错误地认为 .json 文件是 XML。

        【讨论】:

        • 错了。它是有效的javascript,如果你把它解释为javascript,那就没问题了。但是,JSON 比 javascript 更严格,并且 JSON 格式由符合要求的客户端单独解析,而不是“Javascript”。任何与规范兼容的 JSON 解析器都将未引用的键视为错误。
        • 重申一下,JSON 是 javascript 的 子语言,而 ALL JSON 是有效的 javascript,NOT 所有 Javascript是有效的 JSON。
        • 如果您不同意我的观点,请向 Mozilla 投诉,因为您认为他们的 JSON 解析器是错误的 =)。 jsfiddle.net/kentnl/uGDQP
        • 我不得不说,要求密钥具有“”是 JSON 中的一个主要缺陷。这是额外的低迷,JS证明它不是必需的。它可能是为了容纳解析器编写器,并且解析器编写器的数量远远少于用户。我也为无法传递函数而感到悲痛,但这至少是有道理的。
        • “JavaScript Object Notation”这个名字也有误导性。它与 Javascript 中使用的符号不同。
        【解决方案6】:

        我发现了相同的错误消息,但原因却截然不同。经过一段时间无果而终地更改 JSON 内容后,我意识到我不小心重新启动了在本地文件系统 (file://Users/me/Sites/mypage.html) 而不是服务器 (http://localhost/) 上运行的页面~me/Sites/mypage.html)。

        【讨论】:

          【解决方案7】:

          在请求服务器标记为 Content-Type: application/json 的资源时,我也收到了与 XMLHttpRequest()(在 FireFox 中)相同的警告消息。

          对我来说,诀窍是将请求对象上的XMLHttpRequest.responseType 属性显式设置为json。例如,

          var request = new XMLHttpRequest();
          request.onreadystatechange = function() { ... }
          ...
          request.open('GET','https://random-domain.com/random-path',true);
          request.responseType = 'json';
          ...
          request.send();
          

          【讨论】:

            【解决方案8】:
            Browser --- request expects a given content-type ---> Server
                    <-- response contains content-type ----------
            

            Firefox 查看 HTTP Content-Type header。 如果服务器 HTTP 响应标头与您的浏览器代码的期望不匹配,它将抱怨此消息。

            恕我直言,此错误消息可能会好很多,例如“期望响应 Content-Type 标头...但找到...”。

            【讨论】:

              【解决方案9】:

              除非有特殊原因直接从磁盘打开 HTML (file://),否则您应该帮自己一个忙,并通过本地 HTTP 服务器 (http://) 打开它,例如 the prototype user has written。这将解决此问题,因为 MIME type will be set correctly, as jthompson suggested.

              感谢您也不会遇到另一个问题,例如“Reason: CORS request not HTTP”,可能还有其他问题,因为浏览器在被要求打开本地磁盘上的文件时变得越来越可疑 - 并且有充分的理由(安全!)。


              如果您的系统上有 Python,那么 the (arguably) easiest way to run a local HTTP server 是:

              Mac/Linux: python3 -m http.server

              Windows: python -m http.serverpy -3 -m http.server

              然后,当前工作目录中的文件将在 http://localhost:8000/ 下提供服务

              【讨论】:

                猜你喜欢
                • 2013-09-21
                • 1970-01-01
                • 2014-01-13
                • 2011-04-28
                • 2011-02-06
                • 2016-05-24
                • 2016-02-04
                • 2016-04-08
                • 1970-01-01
                相关资源
                最近更新 更多