잡히지 않은 구문 오류 : JSON.parse가있는 예기치 않은 토큰


192

세 번째 줄 에서이 오류의 원인은 무엇입니까?

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

답변:


220

products객체입니다. (객체 리터럴에서 생성)

JSON.parse()JSON 표기법이 포함 된 문자열 을 Javascript 객체로 변환하는 데 사용됩니다 .

코드는 객체를 .toString()JSON 텍스트로 구문 분석하기 위해을 호출하여 객체를 문자열로 변환 합니다.
기본값 .toString()은을 반환 "[object Object]"하며 이는 유효한 JSON이 아닙니다. 따라서 오류.


1
배열이 아닙니까? 왜 객체입니까? 객체는 {로 시작하고 배열은 [? 또는 여기에 거짓입니다

4
배열은 객체입니다. 그것이 .toString()사양에 따라 반환되는 것입니다.
SLaks

1
객체를 먼저 스트링 화하는 솔루션입니까?
Mohammed Noureldin

6
@MohammedNoureldin : 아니오; 해결책은 아무것도하지 않고 객체를 사용하는 것입니다.
SLaks

2
Ajax를 사용하여 원격 서비스에서 데이터를 가져 오면 Json 응답이 다시 제공됩니다. 그리고 그 응답을 JavaScript 배열 객체에 저장하고 싶습니다.
Mohammed Noureldin

125

그것이 유효한 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
Benjamin Hoffman

Base64 디코딩 후 후미의 특수 문자를 얻었으므로 귀하의 방법이 많은 도움이되었습니다! Thx
기 illa

잘못된 JSON으로 응답하는 소스를 신뢰하지 마십시오. 데이터가 손상되었다고 알려주십시오. 그들은 그것을 고쳐야한다. 이와 같은 또는 유사한 방식으로 응답을 "복구"하려고하면 불안정한 통신을 유지하게됩니다.
Onur Yıldırım

모든 제어 문자를 바꾸려면 s = s.replace(/[\u0000-\u001F]+/g,""); 대신 이어야 s = s.replace(/[\u0000-\u0019]+/g,""); 합니다. 권리?
HongchaoZhang

64

객체 를 문자열 화 하려는 것 같습니다 . 이렇게하십시오 :

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

비슷한 문제가 있었지만 "\ n"대신 경로 안에 "\ e"가있었습니다 ( "\"대신 "/"를 사용하도록 서버 측 코드를 변경했으며 모든 것이 다시 작동했습니다)
Adam Tal

\ n \\ n 인 이스케이프를 사용하십시오
Paul Gregoire

14

JSON.parse가 문자열 입력 매개 변수를 기다리고 있습니다. 문제점을 해결하려면 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 yep, OP는 제품을 직접 사용할 수 있습니다. 그러나 JSON.parse그가을 사용 하려면 인수는 문자열이어야합니다.
pktangyue

'이 코멘트이기 때문에 ASP Classic에서 어떻게해야합니까?
ashish bhatt

1
@ashishbhatt 당신은 "를 사용할 수 있습니다 다음 다른 모든"를 \ "로 변경
pktangyue

2
이와 같은 것JSON.parse(products.replace(/'/g, '"'))
화학 프로그래머

11

여기서 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

products는 직접 사용할 수있는 배열입니다.

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에서 테스트 한 결과 34, 92 또는 0에서 31 사이의 JSON.parse(String.fromCharCode(0x22, x, 0x22));위치 x는 허용되지 않습니다 .

문자 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

"예기치 않은 토큰 o"와 같은 오류는 json이 예상되지만 구문 분석하는 동안 객체가 얻어지기 때문입니다. "o"는 "object"라는 단어의 첫 글자입니다.


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.stringify(obj);객체를 JSON으로 변환하지만 JQUERY 표현식이라는 것을 기억하십시오.


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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.