未捕获的SyntaxError:带有JSON.parse的意外令牌


190

是什么导致第三行出现此错误?

var products = [{
  "name": "Pizza",
  "price": "10",
  "quantity": "7"
}, {
  "name": "Cerveja",
  "price": "12",
  "quantity": "5"
}, {
  "name": "Hamburguer",
  "price": "10",
  "quantity": "2"
}, {
  "name": "Fraldas",
  "price": "6",
  "quantity": "2"
}];
console.log(products);
var b = JSON.parse(products); //unexpected token o

打开控制台以查看错误


16
您没有任何JSON吗?这是一个数组/对象文字。
Bergi

Answers:


219

products是一个对象。(从对象文字创建)

JSON.parse()用于将包含JSON表示法的字符串转换为Javascript对象。

您的代码将对象转换为字符串(通过调用.toString()),以尝试将其解析为JSON文本。
默认.toString()返回"[object Object]",这是无效的JSON;因此错误。


1
它不是数组吗?为什么是对象。对象以{开头,数组以[?开头 还是我在这里错了

4
数组是对象;这就是.toString()回报(按照规范)。
SLaks'Sep

1
是首先将对象字符串化的解决方案?
Mohammed Noureldin

6
@MohammedNoureldin:不;解决方案是不执行任何操作并使用您的对象。
凌晨

1
如果我使用Ajax从远程服务中获取数据,这会给我Json响应,该怎么办?我希望将该响应保存在JavaScript数组对象中?
Mohammed Noureldin

126

假设您知道它是有效的JSON,但您仍在获取此信息...

在这种情况下,很可能字符串中包含隐藏/特殊字符,无论您从何处获取它们。当您粘贴到验证器中时,它们会丢失-但是在字符串中它们仍然存在。这些字符不可见,但会破裂JSON.parse()

如果s您的原始JSON是,请使用以下命令进行清理:

// preserve newlines, etc - use valid JSON
s = s.replace(/\\n/g, "\\n")  
               .replace(/\\'/g, "\\'")
               .replace(/\\"/g, '\\"')
               .replace(/\\&/g, "\\&")
               .replace(/\\r/g, "\\r")
               .replace(/\\t/g, "\\t")
               .replace(/\\b/g, "\\b")
               .replace(/\\f/g, "\\f");
// remove non-printable and other non-valid JSON chars
s = s.replace(/[\u0000-\u0019]+/g,""); 
var o = JSON.parse(s);

我遇到了错误,并在字符串中找到了一个奇怪的字符。我使用了您的方法来删除无效的JSON字符,并且可以正常工作。
albertski

1
现在来过这里两次。thnx
本杰明·霍夫曼

在Base64解码后得到一个尾随的特殊字符,您的方法对我有很大帮助!Thx
Guillaume

不要相信使用无效JSON进行响应的源。只需告知他们数据已损坏。他们应该修复它。如果您尝试以这种方式或类似方式“恢复”响应,则将保持不稳定的通信。
OnurYıldırım2016年

应该s = s.replace(/[\u0000-\u001F]+/g,""); 替换为s = s.replace(/[\u0000-\u0019]+/g,""); ,以替换所有控制字符。对?
HongchaoZhang 2016年

63

似乎您想对对象进行字符串化。这样做:

JSON.stringify(products);

究其原因,错误是JSON.parse()需要一个String值,products是一个Array

注意:我认为它会尝试json.parse('[object Array]')在抱怨之后没有期望令牌的情况下o进行尝试[


28

我发现与相同的问题JSON.parse(inputString)

在我的情况下,输入字符串来自服务器页面[返回页面方法]

我打印了typeof(inputString)-它是字符串,仍然发生错误。

我也尝试过JSON.stringify(inputString),但是没有帮助。

后来,我发现这与[\n]字段值内的新行运算符有关。

我做了一个替换(用其他字符,在解析后放回新行),一切正常。


2
换行符也是我的问题。那么我们如何恢复这些数据呢?
kolenda

@kolenda您的JSON无效。您需要更改服务器以使用返回有效JSON的实际JSON序列化程序。
SLaks

我遇到了类似的问题,但是在路径中有一个“ \ e”,而不是“ \ n”(我将服务器端代码更改为使用“ /”而不是“ \”,并且一切再次正常运行)
Adam Tal

使用其中\ n为\\ n的转义字符
Paul Gregoire

13

JSON.parse正在等待参数中的String。您需要对JSON对象进行字符串化处理才能解决此问题。

products = [{"name":"Pizza","price":"10","quantity":"7"}, {"name":"Cerveja","price":"12","quantity":"5"}, {"name":"Hamburguer","price":"10","quantity":"2"}, {"name":"Fraldas","price":"6","quantity":"2"}];
console.log(products);
var b = JSON.parse(JSON.stringify(products));  //solves the problem

12
products = [{"name":"Pizza","price":"10","quantity":"7"}, {"name":"Cerveja","price":"12","quantity":"5"}, {"name":"Hamburguer","price":"10","quantity":"2"}, {"name":"Fraldas","price":"6","quantity":"2"}];

改成

products = '[{"name":"Pizza","price":"10","quantity":"7"}, {"name":"Cerveja","price":"12","quantity":"5"}, {"name":"Hamburguer","price":"10","quantity":"2"}, {"name":"Fraldas","price":"6","quantity":"2"}]';

2
@SLaks是的,OP可以直接使用产品。但如果他要使用JSON.parse,则args必须是字符串。
pktangyue 2013年

我应该在ASP Classic中做什么,因为'是注释
ashish bhatt

1
@ashishbhatt,您可以使用“,然后将所有其他“更改为”
pktangyue 2015年

2
像这样的东西JSON.parse(products.replace(/'/g, '"'))
化学程序员

10

您应该在此处验证JSON字符串。

有效的JSON字符串必须在键周围加上双引号:

JSON.parse({"u1":1000,"u2":1100})       // will be ok

如果没有引号,将导致错误:

JSON.parse({u1:1000,u2:1100})    
// error Uncaught SyntaxError: Unexpected token u in JSON at position 2

使用单引号也会导致错误:

JSON.parse({'u1':1000,'u2':1100})    
// error Uncaught SyntaxError: Unexpected token ' in JSON at position 1

在我的情况下,Grails 2.5.6 render ([key: value])用单引号引起来,导致在jQuery Ajax中位置1处出现JSON parseError。render (groovy.json.JsonOutput.toJson ([key:value]))帮助了我。
philburns


3
[
  {
    "name": "Pizza",
    "price": "10",
    "quantity": "7"
  },
  {
    "name": "Cerveja",
    "price": "12",
    "quantity": "5"
  },
  {
    "name": "Hamburguer",
    "price": "10",
    "quantity": "2"
  },
  {
    "name": "Fraldas",
    "price": "6",
    "quantity": "2"
  }
]

这是您可以解析的完美Json。


3

这是我根据之前的答复做出的功能:它可以在我的机器上使用,但可以在YMMV上使用。

          /**
             * @description Converts a string response to an array of objects.
             * @param {string} string - The string you want to convert.
             * @returns {array} - an array of objects.
            */
            function stringToJson(input) {
              var result = [];

              //replace leading and trailing [], if present
              input = input.replace(/^\[/,'');
              input = input.replace(/\]$/,'');

              //change the delimiter to 
              input = input.replace(/},{/g,'};;;{');

              // preserve newlines, etc - use valid JSON
              ///programming/14432165/uncaught-syntaxerror-unexpected-token-with-json-parse
            input = input.replace(/\\n/g, "\\n")  
            .replace(/\\'/g, "\\'")
            .replace(/\\"/g, '\\"')
            .replace(/\\&/g, "\\&")
            .replace(/\\r/g, "\\r")
            .replace(/\\t/g, "\\t")
            .replace(/\\b/g, "\\b")
            .replace(/\\f/g, "\\f");
            // remove non-printable and other non-valid JSON chars
            input = input.replace(/[\u0000-\u0019]+/g,""); 

              input = input.split(';;;');

              input.forEach(function(element) {
                // console.log(JSON.stringify(element));

                result.push(JSON.parse(element));
              }, this);

              return result;
            }

2

"SyntaxError: Unexpected token"调用时可能会导致异常的另一个陷阱JSON.parse()是在字符串值中使用以下任何一项:

  1. 换行符。

  2. 制表符(是的,您可以使用Tab键生成的制表符!)

  3. 任何独立的斜杠\(但由于某种原因而不是斜杠/,至少在Chrome上不是。)

(有关完整列表,请参见此处的“ 字符串”部分。)

例如,以下将使您获得此异常:

{
    "msg" : {
        "message": "It cannot
contain a new-line",
        "description": "Some discription with a     tabbed space is also bad",
        "value": "It cannot have 3\4 un-escaped"
    }
}

因此,应将其更改为:

{
    "msg" : {
        "message": "It cannot\ncontain a new-line",
        "description": "Some discription with a\t\ttabbed space",
        "value": "It cannot have 3\\4 un-escaped"
    }
}

我应该说,这使得纯文本格式的JSON格式非常难以阅读。



1

希望这可以帮助其他人。

我的问题是我已经通过AJAX在PHP回调函数中注释了HTML,该函数正在解析注释并返回无效的JSON。

删除注释的HTML后,一切都很好,并且JSON解析没有问题。


0

产品是可以直接使用的数组:

var i, j;

for(i=0;i<products.length;i++)
  for(j in products[i])
    console.log("property name: " + j,"value: "+products[i][j]);

0

现在很明显\r\b\t\f,等不是唯一有问题的字符,可以给你这个错误。

请注意,某些浏览器可能对输入有其他要求JSON.parse

在浏览器上运行以下测试代码:

var arr = [];
for(var x=0; x < 0xffff; ++x){
    try{
        JSON.parse(String.fromCharCode(0x22, x, 0x22));
    }catch(e){
        arr.push(x);
    }
}
console.log(arr);

在Chrome上测试,我发现它不允许JSON.parse(String.fromCharCode(0x22, x, 0x22));x34、92或0到31之间。

字符34和92分别是"\字符,通常是预期的字符,它们已正确转义。字符0到31会给您带来麻烦。

为了帮助调试,在执行操作之前JSON.parse(input),请首先验证输入内容是否包含有问题的字符:

function VerifyInput(input){
    for(var x=0; x<input.length; ++x){
        let c = input.charCodeAt(x);
        if(c >= 0 && c <= 31){
            throw 'problematic character found at position ' + x;
        }
    }
}

0

为什么需要JSON.parse?它已经是对象格式的数组。

最好如下使用JSON.stringify: var b = JSON.stringify(products);

这可能对您有帮助。


0

哦,老兄,到目前为止提供的所有上述答案中的解决方案对我来说都行不通。我刚才有一个类似的问题。我设法用引号包裹来解决它。参见屏幕截图。喔。

在此处输入图片说明

原版的:

var products = [{
  "name": "Pizza",
  "price": "10",
  "quantity": "7"
}, {
  "name": "Cerveja",
  "price": "12",
  "quantity": "5"
}, {
  "name": "Hamburguer",
  "price": "10",
  "quantity": "2"
}, {
  "name": "Fraldas",
  "price": "6",
  "quantity": "2"
}];
console.log(products);
var b = JSON.parse(products); //unexpected token o



0

您正在做的唯一错误是,您正在解析已解析的对象,因此它会引发错误,请使用此对象,您将可以正常使用。

var products = [{
  "name": "Pizza",
  "price": "10",
  "quantity": "7"
}, {
  "name": "Cerveja",
  "price": "12",
  "quantity": "5"
}, {
  "name": "Hamburguer",
  "price": "10",
  "quantity": "2"
}, {
  "name": "Fraldas",
  "price": "6",
  "quantity": "2"
}];
console.log(products[0].name); //name of item at 0th index

如果要打印整个json,请使用JSON.stringify()



0

我有这个错误,因为返回json对象的API给出了一个错误(在我的情况下为Code Igniter,当php代码失败时返回html),所以它不是JSON对象。

检查SQL语句和PHP代码,并使用Postman(或其他一些API测试器)对其进行测试


0

我正在做的错误是null(不知不觉地)传递到JSON.parse()中。

所以扔了 Unexpected token n in JSON at position 0


-24

使用eval。它以JavaScript表达式/代码为字符串,并对其进行评估/执行。

eval(inputString);

每次调用eval()都会创建一个新的JavaScript解释器实例。这可能是资源浪费。
Yëco
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.