为啥我的 PATCH 请求的响应是空的? (Javascript)

Posted

技术标签:

【中文标题】为啥我的 PATCH 请求的响应是空的? (Javascript)【英文标题】:Why is my PATCH request's response empty ? (Javascript)为什么我的 PATCH 请求的响应是空的? (Javascript) 【发布时间】:2021-07-30 19:26:13 【问题描述】:

我有一个应用在后端运行 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

【问题讨论】:

你能显示响应正文是什么吗? 尝试将响应对象打印到控制台以查看我们正在处理的内容。 .then(resp =&gt; console.log(resp) 嘿——你能显示这条路线的相应控制器动作吗?(以及与返回你可能在关注点或库中可能有的数据对象相关的任何逻辑) @Joel_Blum,我用更多信息更新了这个问题。谢谢你们的帮助。 【参考方案1】:

看起来有一个204 响应,这是我对成功的PATCH 的期望,这意味着服务器没有返回任何内容。这肯定会解释您遇到的问题。

基本上,我不希望能够在缺席的内容上致电 .text() 或更具体地说是 .json()

理想情况下,PUTPATCH 请求不应返回数据。 200s 是可以接受的,但在我看来,204s 是最合适的

【讨论】:

可以看到报错信息中指定了body stream already read,表示他多次使用.json().text() 在这种情况下你可能是对的,如果失败的代码不是这里发布的代码。但是,我倾向于认为真正的问题源于这样一个事实,即首先没有对访问的 JSON 响应 @gear4 它说'已经读',因为响应正文是空的,所以没有任何东西可以转换为 javascript 对象。 不是此代码中的问题。如果有 no 内容,那么 JSON 错误将是 "Unexpected end of JSON input" 这是一个 应该 显示两个错误消息的可能(它是返回的端点上的 DELETE没有内容的 204:fetch("https://reqres.in/api/users/2", method: "DELETE" ).then(data =&gt; data.json(); data.json()) 查看回复,是204 不是吗?可能是错的,不知道对应的控制器动作是什么样子的,但是看起来像是没有内容的情况【参考方案2】:

注意:我误读了问题,只继续调试器值而不是完全阅读问题。这是问题的正确答案:https://***.com/a/67453072/1710359。我会保留这个答案,以防其他人也有这个问题。

原始答案

失败的代码不是在提供的代码中。

这是由多次使用 .json() 引起的,并且(我假设)位于第二个 .then() 调用中。

请修改您的代码并确保每次请求只调用.json() 一次 次,因为.json() 会使用结果正文。

您可以通过使用.bodyUsed 变量来监控正文是否已被消耗,该变量在任何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()`

【讨论】:

非常感谢。你是对的。缺少的部分是我的 GamesController #update 方法 render json: game 丢失,这对于本次活动至关重要。 @murat-ogulcan-sahin 很高兴我的回答为您指明了正确的方向。不过,我认为您应该将 Damilare 的问题标记为答案,因为它比我的答案更好地回答了最初的问题。

以上是关于为啥我的 PATCH 请求的响应是空的? (Javascript)的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 Eclipse 工作区是空的?

为啥我的相机胶卷模式是空的?

为啥我的 CSRF 令牌在使用 Form::open() 时是空的?

谁能告诉我为啥我的过滤数组是空的?

为啥我的数据库对象的集合是空的?

为啥我的 ComboBox 是空的,尽管变量已初始化?