为什么我的 PATCH 请求的响应是空的? (Javascript)
Why is my PATCH request's response empty ? (Javascript)
我有一个应用在后端运行 Rails,在前端运行 Javascript。我的控制器、路由和 CORS 都很好。我的 Post 和 Get 请求工作正常。然而,当我发出补丁请求时,它成功地进行了补丁,但是作为 response.text()
,我得到的是空字符串。所以当我使用 response.json()
时,它给了我 Uncaught (in promise) SyntaxError: Unexpected end of JSON input at game.js:25 error.
我需要知道问题的根源。
static patchGame() {
const numberOfClicks = parseInt(document.getElementById('click-number').textContent, 10)
const score = parseInt(document.getElementById('score').textContent,10)
const gameID = document.getElementById('gameID').value
const gameObj = {game: {click_number: numberOfClicks, score: score}}
const options = {
method: "PATCH",
headers: {"Content-Type": "application/json",
"Accept": "application/json"},
body: JSON.stringify(gameObj)
}
fetch(`http://localhost:3000/games/${gameID}`, options).then(resp => {debugger}).then(game => { debugger }) // NEVER HITS last debugger
}
这些是我得到的 resp 调试器值,
>resp
<-Response {type: "cors", url: "http://localhost:3000/games/28", redirected: false, status: 204, ok: true, …}
body: ReadableStream
bodyUsed: false
headers: Headers {}
ok: true
redirected: false
status: 204
statusText: "No Content"
type: "cors"
url: "http://localhost:3000/games/28"
__proto__: Response
>resp.text()
<-Promise {<pending>}
__proto__: Promise
[[PromiseState]]: "pending"
[[PromiseResult]]: undefined
>resp.json()
<-Promise {<rejected>: TypeError: Failed to execute 'json' on 'Response': body stream already read
at eval (eval at <a…}
__proto__: Promise
[[PromiseState]]: "rejected"
[[PromiseResult]]: TypeError: Failed to execute 'json' on 'Response': body stream already read at eval (eval at <anonymous> (file:///Users/muratogulcansahin/Desktop/DanceMemory/frontend/game.js:1:1), <anonymous>:1:6) at file:///Users/muratogulcansahin/Desktop/DanceMemory/frontend/game.js:24:84
message: "Failed to execute 'json' on 'Response': body stream already read"
stack: "TypeError: Failed to execute 'json' on 'Response': body stream already read\n at eval (eval at <anonymous> (file:///Users/muratogulcansahin/Desktop/DanceMemory/frontend/game.js:1:1), <anonymous>:1:6)\n at file:///Users/muratogulcansahin/Desktop/DanceMemory/frontend/game.js:24:84"
__proto__: Error
>resp.body
<-ReadableStream {locked: true}
locked: true
__proto__: ReadableStream
看起来有一个 204
响应,这是我对成功 PATCH
的期望,这意味着没有内容从服务器 return 编辑。这肯定可以解释您遇到的问题。
基本上,我不希望能够针对缺失的内容调用 .text()
或更具体地说 .json()
。
理想情况下,PUT
和 PATCH
请求不应 return 数据。 200
是可以接受的,但我认为 204
是最合适的
注意:我有 mis-read 这个问题,并且只继续调试器值而不是完整阅读问题。这是问题的正确答案:https://whosebug.com/a/67453072/1710359。我会留下这个答案 as-is 以防其他人也有这个问题。
原始答案:
失败的代码在提供的代码中不。
这是由于多次使用 .json()
引起的,并且(我假设)位于第二个 .then()
调用中。
请修改您的代码并确保每个请求只调用 .json()
一次 次,因为 .json()
会消耗结果 body。
您可以使用 .bodyUsed
变量监控 body 是否已被消耗,该变量在任何 fetch
响应中都可用。
这是基于您自己的调试器日志的解释:
>resp
<-Response {type: "cors", url: "http://localhost:3000/games/28", redirected:
// prints your server's response data (resp.bodyUsed is now *false*)
>resp.text()
<-Promise {<pending>}
// prints your server's response data as *text*, and *consumes* the body (resp.bodyUsed is now *true*)
>resp.json()
<-Promise {<rejected>: TypeError: Failed to execute 'json' on 'Response': body
// fails to print your server's response data, because you have *already* consumed the body by using `.text()`
我有一个应用在后端运行 Rails,在前端运行 Javascript。我的控制器、路由和 CORS 都很好。我的 Post 和 Get 请求工作正常。然而,当我发出补丁请求时,它成功地进行了补丁,但是作为 response.text()
,我得到的是空字符串。所以当我使用 response.json()
时,它给了我 Uncaught (in promise) SyntaxError: Unexpected end of JSON input at game.js:25 error.
我需要知道问题的根源。
static patchGame() {
const numberOfClicks = parseInt(document.getElementById('click-number').textContent, 10)
const score = parseInt(document.getElementById('score').textContent,10)
const gameID = document.getElementById('gameID').value
const gameObj = {game: {click_number: numberOfClicks, score: score}}
const options = {
method: "PATCH",
headers: {"Content-Type": "application/json",
"Accept": "application/json"},
body: JSON.stringify(gameObj)
}
fetch(`http://localhost:3000/games/${gameID}`, options).then(resp => {debugger}).then(game => { debugger }) // NEVER HITS last debugger
}
这些是我得到的 resp 调试器值,
>resp
<-Response {type: "cors", url: "http://localhost:3000/games/28", redirected: false, status: 204, ok: true, …}
body: ReadableStream
bodyUsed: false
headers: Headers {}
ok: true
redirected: false
status: 204
statusText: "No Content"
type: "cors"
url: "http://localhost:3000/games/28"
__proto__: Response
>resp.text()
<-Promise {<pending>}
__proto__: Promise
[[PromiseState]]: "pending"
[[PromiseResult]]: undefined
>resp.json()
<-Promise {<rejected>: TypeError: Failed to execute 'json' on 'Response': body stream already read
at eval (eval at <a…}
__proto__: Promise
[[PromiseState]]: "rejected"
[[PromiseResult]]: TypeError: Failed to execute 'json' on 'Response': body stream already read at eval (eval at <anonymous> (file:///Users/muratogulcansahin/Desktop/DanceMemory/frontend/game.js:1:1), <anonymous>:1:6) at file:///Users/muratogulcansahin/Desktop/DanceMemory/frontend/game.js:24:84
message: "Failed to execute 'json' on 'Response': body stream already read"
stack: "TypeError: Failed to execute 'json' on 'Response': body stream already read\n at eval (eval at <anonymous> (file:///Users/muratogulcansahin/Desktop/DanceMemory/frontend/game.js:1:1), <anonymous>:1:6)\n at file:///Users/muratogulcansahin/Desktop/DanceMemory/frontend/game.js:24:84"
__proto__: Error
>resp.body
<-ReadableStream {locked: true}
locked: true
__proto__: ReadableStream
看起来有一个 204
响应,这是我对成功 PATCH
的期望,这意味着没有内容从服务器 return 编辑。这肯定可以解释您遇到的问题。
基本上,我不希望能够针对缺失的内容调用 .text()
或更具体地说 .json()
。
理想情况下,PUT
和 PATCH
请求不应 return 数据。 200
是可以接受的,但我认为 204
是最合适的
注意:我有 mis-read 这个问题,并且只继续调试器值而不是完整阅读问题。这是问题的正确答案:https://whosebug.com/a/67453072/1710359。我会留下这个答案 as-is 以防其他人也有这个问题。
原始答案:
失败的代码在提供的代码中不。
这是由于多次使用 .json()
引起的,并且(我假设)位于第二个 .then()
调用中。
请修改您的代码并确保每个请求只调用 .json()
一次 次,因为 .json()
会消耗结果 body。
您可以使用 .bodyUsed
变量监控 body 是否已被消耗,该变量在任何 fetch
响应中都可用。
这是基于您自己的调试器日志的解释:
>resp
<-Response {type: "cors", url: "http://localhost:3000/games/28", redirected:
// prints your server's response data (resp.bodyUsed is now *false*)
>resp.text()
<-Promise {<pending>}
// prints your server's response data as *text*, and *consumes* the body (resp.bodyUsed is now *true*)
>resp.json()
<-Promise {<rejected>: TypeError: Failed to execute 'json' on 'Response': body
// fails to print your server's response data, because you have *already* consumed the body by using `.text()`