javascript fetch- 'Response'에서 'json'실행 실패 : 본문 스트림이 잠겨 있습니다.


112

요청 상태가 400 (400, 423, 429 상태를 시도했습니다)보다 크면 fetch에서 반환 된 json 콘텐츠를 읽을 수 없습니다. 브라우저 콘솔에 다음 오류가 표시됩니다.

Uncaught (in promise) TypeError : 'Response'에서 'json'을 실행하지 못했습니다 : 본문 스트림이 잠겨 있습니다.

반환 된 응답 객체의 내용을 다음과 같이 표시했습니다.

여기에 이미지 설명 입력

하지만 몇 달 전에도 사용할 수 있습니다.

내 질문은 다음과 같습니다.

  • 이것은 Chrome 브라우저의 동작입니까 아니면 가져 오기 표준 변경 사항입니까?
  • 이러한 상태의 본문 내용을 얻을 수있는 방법이 있습니까?

PS : 내 브라우저 버전은 Google Chrome 70.0.3538.102 (正式 版本) (64 位)입니다.


즉, API에서 응답을 받았지만 유효한 json이 아닙니다. 요청에 필요한 모든 매개 변수를 보내고 있습니까?
kiranvj

@kiranvj 내 데이터, 동일한 내용을 확인했으며 올바르게 가져 오기 위해 상태 코드를 200으로 변경했습니다.
Luna

1
같은 문제가 있는데 내 상태가 200인데 결국 어떻게 해결 했나요?
DavSev

@DavSev 특정 상태 코드의 경우 axios를 통해 반환 데이터를 얻습니다
Luna

1
200에서도 발생합니다.
schlingel

답변:


182

이 오류도 만났지만 응답 상태와 관련이 없다는 것을 알았습니다. 진짜 문제는 Response.json()한 번만 사용할 수 있다는 것입니다. 두 번 이상 소비하면 오류가 발생합니다.

아래와 같이 :

    fetch('http://localhost:3000/movies').then(response =>{
    console.log(response);
    if(response.ok){
         console.log(response.json()); //first consume it in console.log
        return response.json(); //then consume it again, the error happens

    }

따라서 해결책은 블록 Response.json()에서 두 번 이상 소비하는 것을 피하는 것 then입니다.


6
response.clone()소비하기 전에 할 수 있습니다.
balduran

좋은. 나는 console.log(r.json()); return r.json();그것을 깨뜨렸다.
mewc

2
저를 위해 일해 주셔서 감사합니다 ..... 누군가이 이상한 행동을 설명 할 수 있습니까?
Sachin

고마워요, 이건 완벽하게 작동했습니다
Ronny Perez

74

Response.clone()복제에 사용Response

fetch('yourfile.json').then(res=>res.clone().json())

19
이것은 나를 위해 잘 작동했지만 왜 이것이 필요한지 이해하는 사람이 있습니까? 나는 그것을 찾아 보았고, 독자가를 읽기 시작하면 때때로 Response.body그 독자에게 고정되는 것을 보았다 . 그러나 내가 볼 수있는 것 (적어도 내 코드에서), 아무것도 읽기 시작하지 않았습니다 ... 읽을 수있는 스트림이 어떻게 자동으로 잠길 수 있는지에 대한 설명이 있습니까?
jenming

6
같은 문제가 있었지만 크롬 개발 도구의 시계 패널에 "res.json ()"이 있다는 것을 알았습니다. 코드 자체보다 먼저 해결되었습니다!
FelipeDrumond

1
무엇을 기다립니다? @FelipeDrumond 그건 미친 (비) 버그입니다!
George Mauer

@GeorgeMauer 글쎄요, response.json ()을 한 번만 실행할 수 있고 크롬 개발 도구 시계 패널이 코드 전에 실행하면 예외가 발생합니다. 왜냐하면 response.json ()을 두 번 실행했기 때문입니다!
FelipeDrumond

참조 MDN
foxiris

8

'json', 'text'와 같은 응답 방법은 한 번만 호출하면 잠 깁니다. 게시 된 응답 이미지는 본문이 잠겨 있음을 보여줍니다. 이것은 당신이 이미 'then', 'catch'를 불렀음을 의미합니다. 이것을 다시 사랑하기 위해 다음을 시도 할 수 있습니다.

fetch(url)
    .then(response=> response.body.json())
    .then(myJson=> console.log(myJson))

또는

fetch(url)
    .catch(response=> response.body.json())
    .catch(myJson=> console.log(myJson))

4

너무 늦었지만 누군가에게 도움이 될 수 있습니다.

let response = await fetch(targetUrl);
let data = await response.json();

async / await 구문을 사용하여이 문제를 해결하는 데 정확히 필요한 것, 감사합니다!
ttemple

2

나도 이것에 집착했다. 그러나 이것은 나를 위해 일했습니다.

fetch(YOUR_URL)
.then(res => {
  try {
    if (res.ok) {
      return res.json()
    } else {
      throw new Error(res)
    }
  }
  catch (err) {
    console.log(err.message)
    return WHATEVER_YOU_WANT_TO_RETURN
  }
})
.then (resJson => {
  return resJson.data
})
.catch(err => console.log(err))

행운을 빕니다



1

실수로 다음과 비슷한 응답 객체를 재사용했습니다.

const response = await new ReleasePresetStore().findAll();
const json = await response.json();
this.setState({ releasePresets: json });

const response2 = await new ReleasePresetStore().findActive();
const json2 = await response.json();
this.setState({ active: json2 });
console.log(json2);

이 줄 :

const json2 = await response.json();

(사용 된 response1 대신 response2) :

const json2 = await response2.json();

이전 응답을 재사용하는 것은 의미가 없었으며 더러운 코드 오타였습니다.


1

이것은 나를 위해 일했습니다.

response.json().then(data => {
  // use data
})

0

동일한 응답 객체를 사용하려고 할 때 질문에서 언급했듯이 객체의 상태로 인해 신체가 잠기려고합니다. 할 수있는 일은 응답 객체의 값을 캡처 한 다음 이에 대한 작업 (.then ())을 시도하는 것입니다. 아래 코드를 따르십시오.

fetch('someurl').then(respose) => {
    let somedata = response.json(); // as you will capture the json response, body will not be locked anymore. 
    somedata.then(data) => {
        {
             error handling (if (data.err) { ---- })
        }
        {
             operations (else { ---- })
        }
    } 
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.