【问题标题】:"SyntaxError: Unexpected token < in JSON at position 0"“SyntaxError:意外的令牌 < 在 JSON 中的位置 0”
【发布时间】:2020-02-05 04:44:38
【问题描述】:

在处理类似 Facebook 的内容提要的 React 应用程序组件中,我遇到了一个错误:

Feed.js:94 undefined "parsererror" "SyntaxError: Unexpected token

我遇到了类似的错误,结果证明是渲染函数中的 HTML 中的拼写错误,但这里的情况似乎并非如此。

更令人困惑的是,我将代码回滚到更早的已知工作版本,但我仍然收到错误消息。

Feed.js:

import React from 'react';

var ThreadForm = React.createClass({
  getInitialState: function () {
    return {author: '', 
            text: '', 
            included: '',
            victim: ''
            }
  },
  handleAuthorChange: function (e) {
    this.setState({author: e.target.value})
  },
  handleTextChange: function (e) {
    this.setState({text: e.target.value})
  },
  handleIncludedChange: function (e) {
    this.setState({included: e.target.value})
  },
  handleVictimChange: function (e) {
    this.setState({victim: e.target.value})
  },
  handleSubmit: function (e) {
    e.preventDefault()
    var author = this.state.author.trim()
    var text = this.state.text.trim()
    var included = this.state.included.trim()
    var victim = this.state.victim.trim()
    if (!text || !author || !included || !victim) {
      return
    }
    this.props.onThreadSubmit({author: author, 
                                text: text, 
                                included: included,
                                victim: victim
                              })
    this.setState({author: '', 
                  text: '', 
                  included: '',
                  victim: ''
                  })
  },
  render: function () {
    return (
    <form className="threadForm" onSubmit={this.handleSubmit}>
      <input
        type="text"
        placeholder="Your name"
        value={this.state.author}
        onChange={this.handleAuthorChange} />
      <input
        type="text"
        placeholder="Say something..."
        value={this.state.text}
        onChange={this.handleTextChange} />
      <input
        type="text"
        placeholder="Name your victim"
        value={this.state.victim}
        onChange={this.handleVictimChange} />
      <input
        type="text"
        placeholder="Who can see?"
        value={this.state.included}
        onChange={this.handleIncludedChange} />
      <input type="submit" value="Post" />
    </form>
    )
  }
})

var ThreadsBox = React.createClass({
  loadThreadsFromServer: function () {
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      cache: false,
      success: function (data) {
        this.setState({data: data})
      }.bind(this),
      error: function (xhr, status, err) {
        console.error(this.props.url, status, err.toString())
      }.bind(this)
    })
  },
  handleThreadSubmit: function (thread) {
    var threads = this.state.data
    var newThreads = threads.concat([thread])
    this.setState({data: newThreads})
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      type: 'POST',
      data: thread,
      success: function (data) {
        this.setState({data: data})
      }.bind(this),
      error: function (xhr, status, err) {
        this.setState({data: threads})
        console.error(this.props.url, status, err.toString())
      }.bind(this)
    })
  },
  getInitialState: function () {
    return {data: []}
  },
  componentDidMount: function () {
    this.loadThreadsFromServer()
    setInterval(this.loadThreadsFromServer, this.props.pollInterval)
  },
  render: function () {
    return (
    <div className="threadsBox">
      <h1>Feed</h1>
      <div>
        <ThreadForm onThreadSubmit={this.handleThreadSubmit} />
      </div>
    </div>
    )
  }
})

module.exports = ThreadsBox

在 Chrome 开发者工具中,错误似乎来自这个函数:

 loadThreadsFromServer: function loadThreadsFromServer() {
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      cache: false,
      success: function (data) {
        this.setState({ data: data });
      }.bind(this),
      error: function (xhr, status, err) {
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  },

console.error(this.props.url, status, err.toString() 下划线。

由于看起来错误似乎与从服务器提取 JSON 数据有关,我尝试从空白数据库开始,但错误仍然存​​在。该错误似乎是在无限循环中调用的,大概是因为 React 不断尝试连接到服务器并最终导致浏览器崩溃。

编辑:

我使用 Chrome 开发工具和 Chrome REST 客户端检查了服务器响应,数据似乎是正确的 JSON。

编辑 2:

看起来虽然预期的 API 端点确实返回了正确的 JSON 数据和格式,但 React 正在轮询 http://localhost:3000/?_=1463499798727 而不是预期的 http://localhost:3001/api/threads。

我正在端口 3000 上运行 webpack 热重载服务器,并在端口 3001 上运行 express 应用程序以返回后端数据。令人沮丧的是,我上次处理它时它工作正常,但找不到我可能改变的东西来破坏它。

【问题讨论】:

  • 这表明您的“JSON”实际上是 HTML。查看您从服务器返回的数据。
  • 如果您执行JSON.parse("&lt;foo&gt;") 之类的操作会出现此错误——JSON 字符串(您期望使用dataType: 'json')不能以&lt; 开头。
  • 正如@quantin 所说,它可以是 html,也可能是某种错误,请尝试与其他客户端相同的 url
  • 就像我提到的,我用一个空数据库(它只返回 [])尝试它,它仍然给出相同的错误
  • 您很可能需要代理 API 请求,具体取决于您的 NODE_ENV。看到这个:github.com/facebookincubator/create-react-app/blob/master/…

标签: javascript json reactjs


【解决方案1】:

您正在从服务器接收 HTML(或 XML),但 dataType: json 告诉 jQuery 解析为 JSON。检查 Chrome 开发工具中的“网络”选项卡以查看服务器响应的内容。

【讨论】:

  • 我检查过,它似乎返回了格式正确的 json。这是响应标头: Access-Control-Allow-Origin:* Cache-Control:no-cache Content-Length:2487 Content-Type:application/json; charset=utf-8 日期:2016 年 5 月 17 日星期二 15:34:00 GMT ETag:W/"9b7-yi1/G0RRpr0DlOVc9u7cMw" X-Powered-By:Express
  • @AVI 我相信你必须在你的资源类中指定 MIME 类型。 (例如)@Produces(MediaType.APPLICATION_JSON)
【解决方案2】:

错误消息的措辞与您在运行 JSON.parse('&lt;...') 时从 Google Chrome 获得的内容相对应。我知道你说服务器正在设置 Content-Type:application/json,但我被引导相信响应 body 实际上是 HTML。

Feed.js:94 undefined "parsererror" "SyntaxError: Unexpected token &lt; in JSON at position 0"

console.error(this.props.url, status, err.toString()) 下划线。

err 实际上是在jQuery 中抛出的,并作为变量err 传递给您。该行带有下划线的原因仅仅是因为您正在记录它。

我建议您添加到您的日志中。查看实际的xhr (XMLHttpRequest) 属性以了解有关响应的更多信息。尝试添加console.warn(xhr.responseText),您很可能会看到正在接收的 HTML。

【讨论】:

  • 谢谢,我这样做了,你是对的——react 正在轮询错误的 url 并返回 index.html 的内容。我就是不知道为什么。
  • 感谢额外的调试语句,虽然我需要使用console.warn(jqxhr.responseText)。这对诊断我的问题很有帮助。
  • @Mimi314159、console.log、console.warn 和 console.error 都会写入您的控制台。但是,控制台通常会提供 Logging Filter 选项,因此请确保根据您的喜好启用或禁用这些选项。
  • 在我的例子中,发生了一个 PHP 错误,导致服务器返回 HTML 而不是有效的 JSON。
  • 您也可以进入开发者设置 -> 网络选项卡以查看您实际得到的响应。当您在同一台服务器(例如本地主机)上运行后端和前端时,就会发生这种情况。要解决此问题,请在 React 根项目文件夹内的 package.json 中添加以下行:"proxy": "http://localhost:5000" ,(或您的端口而不是 5000,您希望返回您的请求)。
【解决方案3】:

按照教程,我收到了相同的错误消息。我们的问题似乎是 ajax 调用中的 'url: this.props.url' 。在 React.DOM 中,当你创建你的元素时,我的看起来像这样。

ReactDOM.render(
    <CommentBox data="/api/comments" pollInterval={2000}/>,
    document.getElementById('content')
);

好吧,这个 CommentBox 的 props 中没有 url,只有数据。当我切换url: this.props.url -> url: this.props.data 时,它对服务器进行了正确的调用,我得到了预期的数据。

希望对你有帮助。

【讨论】:

    【解决方案4】:

    这最终成为我的权限问题。我试图访问一个我没有使用 cancan 授权的 url,所以该 url 被切换到了users/sign_in。重定向的 url 响应 html,而不是 json。 html 响应中的第一个字符是&lt;。

    【讨论】:

    • 我也有同样的情况,尽管在 ASP.NET MVC 中。对于其他 .NETters,我忘记使用 [AllowAnonymous] 属性来装饰我的操作,因此框架试图返回 HTML 中的未经授权的错误,这导致我的 AJAX 调用崩溃。
    【解决方案5】:

    我的情况是错误是我没有将返回值分配给变量的结果。以下导致错误消息:

    return new JavaScriptSerializer().Serialize("hello");
    

    我改成:

    string H = "hello";
    return new JavaScriptSerializer().Serialize(H);
    

    没有变量 JSON 无法正确格式化数据。

    【讨论】:

      【解决方案6】:

      我的问题是我以 string 取回的数据不是正确的 JSON 格式,然后我试图解析它。 simple example: JSON.parse('{hello there}') 将在 h 处给出错误。在我的情况下,回调 url 在对象之前返回了一个不必要的字符:employee_names([{"name":.... 并且在 0 处出现错误。我的回调 URL 本身有一个问题,修复后只返回对象。

      【讨论】:

        【解决方案7】:

        花了很多时间处理这个问题后,我发现问题是在我的 package.json 文件中定义了“主页”,这导致我的应用无法在 firebase 上运行(同样的“令牌”错误)。 我使用 create-react-app 创建了我的 react 应用程序,然后我使用 READ.me 文件上的 firebase 指南部署到 github 页面,意识到我必须做额外的工作才能让路由器工作,然后切换到 firebase。 github 指南在 package.json 上添加了主页键并导致部署问题。

        【讨论】:

          【解决方案8】:

          在我的情况下,我正在运行这个 webpack,结果发现本地 node_modules 目录中的某个地方出现了一些损坏。

          rm -rf node_modules
          npm install
          

          ...足以让它再次正常工作。

          【讨论】:

          • 除此之外,我还尝试删除 package-lock.json。然后它对我有用。
          【解决方案9】:

          我遇到了这个错误“SyntaxError: Unexpected token m in JSON at position”,其中标记“m”可以是任何其他字符。

          原来我在使用 RESTconsole 进行 DB 测试时遗漏了 JSON 对象中的双引号之一,为 {"name: "math"},正确的应该是 {"name": "math" }

          我费了好大劲才弄明白这个笨拙的错误。恐怕其他人也会遇到类似的问题。

          【讨论】:

            【解决方案10】:

            Protip:在本地 Node.js 服务器上测试 json?确保您还没有路由到该路径的东西

            '/:url(app|assets|stuff|etc)';
            

            【讨论】:

              【解决方案11】:

              JSON 中位置 0 的意外标记

              解决此错误的一个简单方法是在styles.less 文件中写入注释。

              【讨论】:

              • 这是我在 Stackoverflow 上见过的最奇怪的答案之一。
              • 您好!发表评论时,请确保它完全适用于所提出的实际问题。如果您告诉我们为什么在 styles.less 文件中准确编写 cmets 可能会解决后端服务器代码问题,您的答案可能会更好。
              【解决方案12】:

              只是为了补充答案,当您的 API 响应包含

              时也会发生这种情况
              <?php{username: 'Some'}
              

              当您的后端使用 PHP 时,可能会出现这种情况。

              【讨论】:

                【解决方案13】:

                就我而言,对于 Azure 托管的 Angular 2/4 站点,我对 mySite/api/... 的 API 调用由于 mySite 路由问题而被重定向。因此,它从重定向页面返回 HTML,而不是 api JSON。我在 web.config 文件中为 api 路径添加了排除项。

                我在本地开发时没有收到此错误,因为站点和 API 位于不同的端口上。可能有更好的方法来做到这一点......但它奏效了。

                <?xml version="1.0" encoding="UTF-8"?>
                
                <configuration>
                    <system.webServer>
                        <rewrite>
                        <rules>
                        <clear />
                
                        <!-- ignore static files -->
                        <rule name="AngularJS Conditions" stopProcessing="true">
                        <match url="(app/.*|css/.*|fonts/.*|assets/.*|images/.*|js/.*|api/.*)" />
                        <conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
                        <action type="None" />
                        </rule>
                
                        <!--remaining all other url's point to index.html file -->
                        <rule name="AngularJS Wildcard" enabled="true">
                        <match url="(.*)" />
                        <conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
                        <action type="Rewrite" url="index.html" />
                        </rule>
                
                        </rules>
                        </rewrite>
                    </system.webServer>
                </configuration>
                

                【讨论】:

                  【解决方案14】:

                  一般来说,当解析一个包含语法错误的 JSON 对象时会发生此错误。想想这样的事情,其中​​ message 属性包含未转义的双引号:

                  {
                      "data": [{
                          "code": "1",
                          "message": "This message has "unescaped" quotes, which is a JSON syntax error."
                      }]
                  }
                  

                  如果您的应用中有 JSON,那么最好通过 JSONLint 运行它以验证它没有语法错误。通常情况并非如此,但根据我的经验,通常是从 API 返回的 JSON 是罪魁祸首。

                  当向 HTTP API 发出 XHR 请求并返回带有 Content-Type:application/json; charset=UTF-8 标头的响应时,响应正文中包含无效的 JSON,您将看到此错误。

                  如果服务器端 API 控制器未正确处理语法错误,并将其作为响应的一部分打印出来,则会破坏返回的 JSON 结构。一个很好的例子是在响应正文中包含 PHP 警告或通知的 API 响应:

                  <b>Notice</b>:  Undefined variable: something in <b>/path/to/some-api-controller.php</b> on line <b>99</b><br />
                  {
                      "success": false,
                      "data": [{ ... }]
                  }
                  

                  95% 的时间这对我来说是问题的根源,尽管在其他回复中有所提及,但我觉得没有明确描述。希望这会有所帮助,如果您正在寻找一种方便的方法来追踪哪个 API 响应包含 JSON 语法错误,我已经写了一个 Angular module for that。

                  这是模块:

                  /**
                   * Track Incomplete XHR Requests
                   * 
                   * Extend httpInterceptor to track XHR completions and keep a queue 
                   * of our HTTP requests in order to find if any are incomplete or 
                   * never finish, usually this is the source  of the issue if it's 
                   * XHR related
                   */
                  angular.module( "xhrErrorTracking", [
                          'ng',
                          'ngResource'
                      ] )
                      .factory( 'xhrErrorTracking', [ '$q', function( $q ) {
                          var currentResponse = false;
                  
                          return {
                              response: function( response ) {
                                  currentResponse = response;
                                  return response || $q.when( response );
                              },
                              responseError: function( rejection ) {
                                  var requestDesc = currentResponse.config.method + ' ' + currentResponse.config.url;
                                  if ( currentResponse.config.params ) requestDesc += ' ' + JSON.stringify( currentResponse.config.params );
                  
                                  console.warn( 'JSON Errors Found in XHR Response: ' + requestDesc, currentResponse );
                  
                                  return $q.reject( rejection );
                              }
                          };
                      } ] )
                      .config( [ '$httpProvider', function( $httpProvider ) {
                          $httpProvider.interceptors.push( 'xhrErrorTracking' );
                      } ] );
                  

                  更多细节可以在上面引用的博客文章中找到,我没有在这里发布所有在这里找到的东西,因为它可能并不完全相关。

                  【讨论】:

                    【解决方案15】:

                    当您将响应定义为 application/json 并且您收到 HTML 作为响应时,会发生此错误。基本上,当您为特定 url 编写服务器端脚本并响应 JSON 但错误格式为 HTML 时,就会发生这种情况。

                    【讨论】:

                      【解决方案16】:

                      对我来说,这发生在我作为 JSON 返回的对象的属性之一引发异常时。

                      public Dictionary<string, int> Clients { get; set; }
                      public int CRCount
                      {
                          get
                          {
                              var count = 0;
                              //throws when Clients is null
                              foreach (var c in Clients) {
                                  count += c.Value;
                              }
                              return count;
                          }
                      }
                      

                      添加一个空检查,为我修复它:

                      public Dictionary<string, int> Clients { get; set; }
                      public int CRCount
                      {
                          get
                          {
                              var count = 0;
                              if (Clients != null) {
                                  foreach (var c in Clients) {
                                      count += c.Value;
                                  }
                              }
                              return count;
                          }
                      }
                      

                      【讨论】:

                        【解决方案17】:

                        只是一些基本的检查,确保你没有在 json 文件中注释掉任何东西

                        //comments here will not be parsed and throw error
                        

                        【讨论】:

                          【解决方案18】:

                          在 python 中,您可以在将结果发送到 html 模板之前使用 json.Dump(str)。 使用此命令字符串转换为正确的 json 格式并发送到 html 模板。将此结果发送到 JSON.parse(result) 后,这是正确的响应,您可以使用它。

                          【讨论】:

                            【解决方案19】:

                            这可能是旧的。但是,它只是发生在角度上,请求和响应的内容类型在我的代码中是不同的。所以,检查标题,

                             let headers = new Headers({
                                    'Content-Type': 'application/json',
                                    **Accept**: 'application/json'
                                });
                            

                            在 React axios 中

                            axios({
                              method:'get',
                              url:'http://  ',
                             headers: {
                                     'Content-Type': 'application/json',
                                    Accept: 'application/json'
                                },
                              responseType:'json'
                            })
                            

                            jQuery Ajax:

                             $.ajax({
                                  url: this.props.url,
                                  dataType: 'json',
                            **headers: { 
                                      'Content-Type': 'application/json',
                                    Accept: 'application/json'
                                },**
                                  cache: false,
                                  success: function (data) {
                                    this.setState({ data: data });
                                  }.bind(this),
                                  error: function (xhr, status, err) {
                                    console.error(this.props.url, status, err.toString());
                                  }.bind(this)
                                });
                              },
                            

                            【讨论】:

                              【解决方案20】:

                              对于某些人来说,这可能会对你们有所帮助: 我对 Wordpress REST API 有过类似的体验。我什至使用 Postman 来检查我是否有正确的路线或端点。后来我发现我不小心在我的脚本中放了一个“回声” - 钩子:

                              Debug & check your console

                              Cause of the error

                              所以基本上,这意味着我打印了一个不是 JSON 的值,它与导致 AJAX 错误的脚本混合 - “SyntaxError: Unexpected token r in JSON at position 0”

                              【讨论】:

                                【解决方案21】:

                                这可能是由于您的 javascript 代码正在查看一些 json 响应而您收到了其他类似文本的内容。

                                【讨论】:

                                • 请在给出答案时详细说明,而不是只给出一个衬里,除非他们彻底解决了答案。解释将有助于寻求答案的人更好地理解解决方案。
                                【解决方案22】:

                                确保响应为 JSON 格式,否则会引发此错误。

                                【讨论】:

                                  【解决方案23】:

                                  那些正在使用create-react-app 并试图获取本地 json 文件的人。

                                  与create-react-app 一样,webpack-dev-server 用于处理请求,并且它为每个请求提供服务index.html。所以你得到了

                                  SyntaxError: 位置 0 处 JSON 中的意外标记

                                  要解决这个问题,您需要弹出应用程序并修改webpack-dev-server 配置文件。

                                  您可以按照here的步骤操作。

                                  【讨论】:

                                    【解决方案24】:

                                    就我而言(后端),我使用的是 res.send(token);

                                    当我更改为 res.send(data); 时,一切都得到了修复;

                                    如果一切正常并按预期发布,您可能需要检查此项,但错误不断在您的前端弹出。

                                    【讨论】:

                                      【解决方案25】:

                                      这个错误的可能性是压倒性的。

                                      就我而言,我发现问题是在package.json 中添加homepage 导致了问题。

                                      值得检查:package.json 更改:

                                      homepage: "www.example.com"
                                      

                                      到

                                      hompage: ""   
                                      

                                      【讨论】:

                                        【解决方案26】:

                                        简而言之,如果您遇到此错误或类似错误,那仅意味着一件事。也就是说,在我们的代码库中的某个地方,我们期望处理有效的 JSON 格式,但我们没有得到。例如:

                                        var string = "some string";
                                        JSON.parse(string)
                                        

                                        会抛出一个错误,说

                                        Uncaught SyntaxError: Unexpected token s in JSON at position 0

                                        因为,string 中的第一个字符是 s 并且它现在不是有效的 JSON。这也可能在两者之间引发错误。喜欢:

                                        var invalidJSON= '{"foo" : "bar", "missedquotehere : "value" }';
                                        JSON.parse(invalidJSON)
                                        

                                        会抛出错误:

                                        VM598:1 Uncaught SyntaxError: Unexpected token v in JSON at position 36
                                        

                                        因为我们故意遗漏了 JSON 字符串 invalidJSON 中第 36 位的引号。

                                        如果你解决了这个问题:

                                        var validJSON= '{"foo" : "bar", "missedquotehere : "value" }';
                                        JSON.parse(validJSON)
                                        

                                        会给你一个 JSON 格式的对象。

                                        现在,可以在任何地方和任何框架/库中引发此错误。大多数时候,您可能正在阅读不是有效 JSON 的网络响应。所以调试这个问题的步骤可以是:

                                        1. curl 或点击您正在调用的实际 API。
                                        2. 记录/复制响应并尝试使用JSON.parse 解析它。如果您遇到错误,请修复它。
                                        3. 如果没有,请确保您的代码没有改变/更改原始响应。

                                        【讨论】:

                                          【解决方案27】:

                                          我遇到了同样的问题。 我从 $.ajax 方法中删除了 dataType:'json'。

                                          【讨论】:

                                            【解决方案28】:

                                            如果其他人正在使用 Mozilla 中 Web API 上的“使用 Fetch”文档中的 fetch: (这个真的很有用:https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)

                                              fetch(api_url + '/database', {
                                                method: 'POST', // or 'PUT'
                                                headers: {
                                                 'Content-Type': 'application/json'
                                                },
                                                body: qrdata //notice that it is not qr but qrdata
                                              })
                                              .then((response) => response.json())
                                              .then((data) => {
                                                console.log('Success:', data);
                                              })  
                                              .catch((error) => {
                                              console.error('Error:', error);  });
                                            

                                            这是在函数内部:

                                            async function postQRData(qr) {
                                            
                                              let qrdata = qr; //this was added to fix it!
                                              //then fetch was here
                                            }
                                            

                                            我将我认为是对象的东西传递给我的函数qr,因为qr 看起来像这样:{"name": "Jade", "lname": "Bet", "pet":"cat"},但我不断收到语法错误。 当我将它分配给其他东西时:let qrdata = qr; 它起作用了。

                                            【讨论】:

                                              【解决方案29】:

                                              在我的情况下,标题中的“Bearer”存在问题,理想情况下它应该是“Bearer”(结束字符后的空格),但在我的情况下,它是“Bearer”,字符后没有空格。希望对大家有所帮助!

                                              【讨论】:

                                                【解决方案30】:

                                                可能会出现一些权限错误,请尝试切换浏览器并从授权帐户登录。

                                                【讨论】:

                                                • 如果您确定解决方案,请使用答案选项,否则您可以选择将其写为对问题的评论。
                                                • 在我的情况下这是可行的,因此将其写为答案。
                                                猜你喜欢
                                                • 2021-09-12
                                                相关资源
                                                最近更新 更多