fetch()接收到200但浏览器未能加载响应数据

huangapple go评论57阅读模式
英文:

fetch() receive 200 but browser failed to load response data

问题

在一个React应用中,我使用fetch如下所示:

fetch()
   .then(res => res.json())
   .then(res => console.log(res)) // 这会打印"undefined"
   .catch(err => console.error(err))

并且响应是200 OK。但我无法在浏览器中看到内容。这个200是由一个Symfony控制器提供的,如下所示:

<?php

namespace App\Controller;

class MoveController extends AbstractController
{
    #[Route('/move', name: 'app_move')]
    public function index(): Response {
        
        // ... 这里有一些内容 ...
        // ... 这里有一些内容 ...
        
        return $this->json([
            'score' => 42,
        ], 200);
    }
}

代码不起作用,每当我点击按钮时,我在控制台中看到当前的日志:

throw `Server error: [${resp.status}] [${resp.statusText}] [${resp.url}]`;

但请注意:resp的内容为空。

fetch()接收到200但浏览器未能加载响应数据

完整的代码如下:

<button onClick={async () => {
            
    const response = await fetch('https://localhost:8000/move', {
        method: 'POST',
        mode: 'no-cors',
        cache: 'no-cache',
        credentials: 'same-origin',
        redirect: 'follow',
        referrerPolicy: 'no-referrer',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({
            'game_id': Math.random(),
            'dices': [1, 2, 3, 4, 5],
            'category': '5',
        }),
    })
    .then((resp) => {
        if (!resp.ok) {
            console.log(resp)
            throw `Server error: [${resp.status}] [${resp.statusText}] [${resp.url}]`;
        }
        return resp.json();
    })
    .then((json) => console.log(json))
    .catch(err => console.error(err))

    console.log(response)

}}>发送到服务器</button>

为什么网络返回200?

fetch()接收到200但浏览器未能加载响应数据

但我无法看到内容?

英文:

In a React app I've used fetch like this:

fetch()
   .then(res =&gt; res.json())
   .then(res =&gt; console.log(res)) // this print &quot;undefined&quot;
   .catch(err =&gt; console.error(err))

And response is 200 ok. But I cant see the content in the browser. The 200 is given by a Symfony controller like this:

&lt;?php

namespace App\Controller;

class MoveController extends AbstractController
{
    #[Route(&#39;/move&#39;, name: &#39;app_move&#39;)]
    public function index(): Response {
        
        // ... some content here ...
        // ... some content here ...
        
        return $this-&gt;json([
            &#39;score&#39; =&gt; 42,
        ], 200);
    }
}

Code is not working and whenever I click on the button I see current log in console:

throw `Server error: [${resp.status}] [${resp.statusText}] [${resp.url}]`;

But see: the content of resp is nothing.

fetch()接收到200但浏览器未能加载响应数据

The full code is here

       &lt;button onClick={async () =&gt; {
            
            const response = await fetch(&#39;https://localhost:8000/move&#39;, {
                method: &#39;POST&#39;,
                mode: &#39;no-cors&#39;,
                cache: &#39;no-cache&#39;,
                credentials: &#39;same-origin&#39;,
                redirect: &#39;follow&#39;,
                referrerPolicy: &#39;no-referrer&#39;,
                headers: {
                    &#39;Content-Type&#39;: &#39;application/json&#39;,
                },
                body: JSON.stringify({
                    &#39;game_id&#39;: Math.random(),
                    &#39;dices&#39;: [1, 2, 3, 4, 5],
                    &#39;category&#39;: &#39;5&#39;,
                }),
            })
                .then((resp) =&gt; {
                    if (!resp.ok) {
                        console.log(resp)
                        throw `Server error: [${resp.status}] [${resp.statusText}] [${resp.url}]`;
                    }
                    return resp.json();
                })
                .then((json) =&gt; console.log(json))
                .catch(err =&gt; console.error(err))

                console.log(response)

        }}&gt;send to server&lt;/button&gt;

Why network return 200?

fetch()接收到200但浏览器未能加载响应数据

But I cant see the content?

答案1

得分: 1

这是 mode: 'no-cors'。尽管它的名称很有前景并且稍微有点误导,但 CORs 并不会因此消失,出于安全原因,您只会得到一个无法读取的响应。尽管在网络面板中它是 200,但从 JavaScript 的角度来看,它的状态代码是 0,它的内容无法看到。您需要移除 mode: 'no-cors' 并确保您的服务器已正确配置了 CORS。

no-cors 用于一些奇怪的边缘情况,用于从不支持 CORs 的服务器加载脚本/图像,浏览器会在不需要您的代码检查响应的情况下本地处理内容。您不能将其用于与您的 API 通信。

基本上:没有逃避配置您的服务器以正确发出相关的 CORS 标头。

英文:

It's the mode: &#39;no-cors&#39;. CORs doesn't just go away with this (despite the promising and slightly misleading name), you'll just get a response you can't read from for security reasons. Even though it's 200 in the network pane, as far as the JS is concerned its status code 0 and its body can not be seen. You need to remove mode: &#39;no-cors&#39; and ensure CORS is correctly configured on your server.

no-cors is for some weird edge cases around loading scripts/images from servers that don't support CORs where the browser handles the contents natively without your code needing to inspect the response. You can't use it for communicating with your API.

Essentially: There is no escaping configuring your server to properly issue the relevant CORS headers.

huangapple
  • 本文由 发表于 2023年6月16日 05:09:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/76485528.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定