英文:
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的内容为空。
完整的代码如下:
<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?
但我无法看到内容?
英文:
In a React app I've used fetch like this:
fetch()
.then(res => res.json())
.then(res => console.log(res)) // this print "undefined"
.catch(err => 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:
<?php
namespace App\Controller;
class MoveController extends AbstractController
{
#[Route('/move', name: 'app_move')]
public function index(): Response {
// ... some content here ...
// ... some content here ...
return $this->json([
'score' => 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.
The full code is here
<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)
}}>send to server</button>
Why network return 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: 'no-cors'
. 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: 'no-cors'
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论