未捕获的语法错误:意外的标记 :

251

我在MooTools脚本中运行一个AJAX调用,在Firefox中可以正常工作,但在Chrome中出现了Uncaught SyntaxError: Unexpected token :错误,我无法确定原因。注释掉代码以确定坏代码所在的位置没有效果,我认为可能是返回的JSON有问题。在控制台中检查后发现返回的JSON如下:

{"votes":47,"totalvotes":90}

我没有看到任何问题,为什么会出现这个错误?

vote.each(function(e){
  e.set('send', {
    onRequest : function(){
      spinner.show();
    },
    onComplete : function(){
      spinner.hide();
    },
    onSuccess : function(resp){
      var j = JSON.decode(resp);
      if (!j) return false;
      var restaurant = e.getParent('.restaurant');
      restaurant.getElements('.votes')[0].set('html', j.votes + " vote(s)");
      $$('#restaurants .restaurant').pop().set('html', "Total Votes: " + j.totalvotes);
      buildRestaurantGraphs();
    }
  });

  e.addEvent('submit', function(e){
    e.stop();
    this.send();
  });
});

1
JSON格式没问题,问题可能出在你的处理方式上。展示代码会有所帮助。 - tcooc
1
已将代码部分添加到问题中。 - trobrock
语法、JS或JSON似乎都没有问题。在jsfiddle.net上发布一个(不)工作的测试用例会有所帮助 - 包括HTML。 - Oskar Krawczyk
您可以在此处检查引起问题的网站:http://trobrock.com:8011,单击“Cat 1”,然后在单击投票时出现问题,目前仅在Chrome中看到了该问题。 - trobrock
1
我目前正在使用网络共享功能,因此我的调制解调器会压缩我浏览的网站的HTML源代码,所以我无法真正理解这些代码。但是,首先将每个JS代码放在外部文件中 - 这总是使调试更容易 - 您将知道错误是由JS还是其他原因引起的。 - Oskar Krawczyk
2
“Unexpected token” 可能是一些非法字符代码。这种代码可能不会在打印到控制台时显示出来。因此,逐个字符地打印字符串或使用协议分析器或调试器等工具来查看字符串的实际字节。 - GroovyDotCom
27个回答

150

查看红色错误

未捕获的 SyntaxError: 意外的标记 <

在您的Chrome 开发者控制台选项卡中看到此错误,是响应主体中包含了HTML。

实际上,您所看到的是浏览器对来自服务器的意外顶部行<!DOCTYPE html>的反应。


34
我不知道为什么你在谈论“意外标记<” ,而问题是关于“意外标记:”的。你的答案与提问者的问题完全无关。请注意修改后重新翻译。 - Michał Perłakowski
4
我该怎么解决这个问题?我使用了一个php重定向,导致在Chrome浏览器中出现了这个问题。 - Works for a Living
16
补充 @andy_magoon 所说的,我遇到的情况是,有一个脚本标签应该提供 JavaScript,但由于请求被重定向到一个 HTML 页面(不重要为什么会重定向),该页面以 <!DOCTYPE html> 开始,它不是有效的 JavaScript 代码,因此当浏览器尝试将 HTML 解析为 JS 时,就会返回 SyntaxError。 - david.barkhuizen
2
@Thom 修复的方法是确保HTTP获取返回你要查找的JavaScript文件,而不是意外的HTML。 - david.barkhuizen
3
我遇到了这个错误,原来是因为文件路径不正确,在脚本标签中指定的文件找不到。我需要对此进行修正。 - newman
显示剩余4条评论

88

提供给可能遇到类似问题的人一些信息 -- 我只需让我的服务器以application/json格式发送JSON数据,jQuery默认的处理程序就可以正常工作了。


4
我认为我正在遇到与此问题相反的情况。我从第三方 API 请求 JSON,但他们返回响应类型为 application/javascript,我遇到了你在这个问题中报告过的同样错误。不确定该如何处理。 - wuliwong
8
一个奇怪的问题是 - 在本地主机上运行良好,但在服务器上却不行。有什么想法吗? - VishwaKumar
你好。我有一个确切的问题,但是我无法解决它,能否有人告诉我如何将 JSON 发送回服务器? - Alen
1
谢谢!我之前一直以为应该使用 application/javascript(因为我误读了这个stackoverflow帖子),导致即使是正确的JSON也会报错。把它改成 application/json 就解决了问题。我没有使用JSONP。 - scipilot
即使我以JSON格式收到响应{"success":true,"data":2593},我仍然遇到相同的错误“Uncaught SyntaxError: Unexpected token :”。 - Rupali Pemare

42

这刚刚发生在我身上,但原因并不是上面提到的任何一个。我正在使用jQuery命令getJSON,并添加callback=?以使用JSONP(因为我需要跨域),并返回JSON代码{"foo":"bar"},但出现了错误。

这是因为我应该包含回调数据,类似于jQuery17209314005577471107_1335958194322({"foo":"bar"})

这是我使用的PHP代码,可在使用JSON(没有回调)时降级:

$ret['foo'] = "bar";
finish();

function finish() {
    header("content-type:application/json");
    if ($_GET['callback']) {
        print $_GET['callback']."(";
    }
    print json_encode($GLOBALS['ret']);
    if ($_GET['callback']) {
        print ")";
    }
    exit; 
}

希望这对未来的某个人有所帮助。


它对我帮助很大。每当我们使用jsonp方法时,应该用jsoncallback数据包装json数据。此外,jsonpcallback数据不应以数字开头。当我尝试使用数字时,它没有成功。当我按照这个答案中显示的相同格式尝试时,它成功了... - Ganesh Babu
足够正确,但错误是相同的,如果正在使用JSON,则代码将优雅地降级并仍然工作。 - Grim...
这对我使用AJAX、jQuery和JSONP起作用了。非常感谢! - Piotr Wittchen

20

我刚刚解决了这个问题。使用标准的请求调用会导致一些问题,所以我改用了以下代码:

vote.each(function(element){                
  element.addEvent('submit', function(e){
    e.stop();
    new Request.JSON({
      url : e.target.action, 
      onRequest : function(){
        spinner.show();
      },
      onComplete : function(){
        spinner.hide();
      },
      onSuccess : function(resp){
        var j = resp;
        if (!j) return false;
        var restaurant = element.getParent('.restaurant');
        restaurant.getElements('.votes')[0].set('html', j.votes + " vote(s)");
        $$('#restaurants .restaurant').pop().set('html', "Total Votes: " + j.totalvotes);
        buildRestaurantGraphs();
      }
    }).send(this);
  });
});

如果有人知道为什么标准的Request对象会给我带来问题,我很想知道。


3
标准请求和request.json之间的区别主要在于头部,它添加了this.headers.extend({'Accept': 'application/json', 'X-Request': 'JSON'}); - 想一想。 - Dimitar Christoff
很奇怪,这就是导致问题的原因。 - trobrock
3
那里的双重符号$$是什么意思? - falsarella
@DimitarChristoff -- 有关$$的任何答案回复falsarella了吗? - bear
1
@bear 双美元选择器是在 MooTools 中定义的。 - Anthony Faull
@melpomene,你是对的。为避免混淆已删除评论。 - neuquen

11

我想把我的问题和解决方法添加到列表中。

我遇到了这个问题:Uncaught SyntaxError: Unexpected token <,错误指向我的ajax成功语句中的这一行:

var total = $.parseJSON(response);

后来我发现,除了json结果之外,还发送了HTML响应,因为我的PHP代码有错误。当你在PHP中出现错误时,你可以设置它以警告巨大的橙色表格,而那些表格就是导致JSON数据出错的原因。

我通过执行console.log(response)来查看实际发送的内容才发现这一点。如果是JSON数据的问题,只需尝试执行console.log或其他语句,以便能够查看发送和接收到的内容。


1
我做到了。我在我的php文件中的某个程序中打印出json数据,但是我的响应中得到的是php[//json data],我无法解析它。感谢您发布这篇文章,这样我就能找到自己的错误了。 - Nicholas Decker
OP问题完全不同。在你的情况下,你正在尝试将HTML解析为JSON,而在OP的情况下,他正在尝试将JSON解析为JavaScript。 - Michał Perłakowski

9
当您请求JSON文件时,服务器返回JavaScript Content-Type头部(text/javascript),而不是JSON(application/json)。
根据MooTools文档

带有javascript内容类型的响应将自动进行评估。

结果MooTools尝试将您的JSON作为JavaScript进行评估,当您尝试评估这样的JSON时:
{"votes":47,"totalvotes":90}

作为JavaScript解析器,它将{}视为块级作用域,而不是对象符号。这与评估以下"代码"相同:
"votes":47,"totalvotes":90

正如您所见,这里的 : 是完全意外的。

解决方法是为JSON文件设置正确的 Content-Type 头信息。如果您使用 .json 扩展名保存它,您的服务器应该会自动处理。


5

听起来你的响应正在被某种方式评估。这在Chrome中会产生相同的错误:

var resp = '{"votes":47,"totalvotes":90}';
eval(resp);

这是因为javascript将大括号“{...}”解释为代码块而不是对象字面量,这可能会导致问题。建议查看JSON.decode()函数并检查其中是否有eval()。 类似的问题可以参考这里:Eval() = Unexpected token : error

2
今天我也遇到了这个问题。我正在使用EF,并在响应AJAX调用时返回一个实体。我的实体上的虚拟属性导致了循环依赖错误,但服务器没有检测到。通过在虚拟属性上添加[ScriptIgnore]属性,问题得到解决。
与其使用ScriptIgnore属性,最好返回一个数据传输对象(DTO)。

2

我之前因为在脚本标签中缺少type属性而遇到了这个错误。

一开始我使用的是 <script> 标签,但当我在脚本标签中添加了 type 属性后,问题得到了解决。


2
这是因为我在我的express服务器中设置了一个规则,将任何404请求路由回/#再加上原始请求。这样就允许angular路由器/js处理请求。如果没有js路由可处理该路径,则会向服务器发出/#/whatever的请求,它只是对整个网页/的请求。
例如,如果我想要请求/correct/somejsfile.js,但我错输入为/wrong/somejsfile.js,请求就会发送到服务器。那个位置/文件不存在,所以服务器响应一个302 location: /#/wrong/somejsfile.js。浏览器会愉快地遵循重定向,返回整个网页。浏览器解析页面作为js,然后您会得到:

Uncaught SyntaxError: Unexpected token <

因此,要找到错误的路径/请求,请查找302请求。希望可以帮助到某些人。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接