如何从Fetch POST请求中获取响应数据?——Chrome网络面板可见返回数据但代码无法访问的解决方案
嘿,我来帮你搞定这个问题!你提到点击按钮触发handleClick方法时,Chrome开发者工具的网络面板明明能看到服务器返回的数据,但代码里就是拿不到,核心问题出在你设置的mode: 'no-cors'上。
为什么会这样?
当你给fetch请求加上mode: 'no-cors'时,浏览器会出于同源策略的安全限制,返回一个不透明响应(opaque response)。这种响应的所有内容(包括body、状态码、headers)对JavaScript代码都是隐藏的——哪怕浏览器本身能接收到服务器的返回(所以你能在网络面板里看到),但就是不让你的代码访问。
解决方案
这里有两种可行的解决办法,根据你的后端情况选择:
方案1:移除no-cors模式(推荐,需后端支持CORS)
如果你的后端服务器(http://127.0.0.1:8000)可以修改,最直接的办法是在后端配置CORS,允许你的前端域名发起跨域请求,然后去掉mode: 'no-cors'。
修改后的代码如下:
let data; async function handleClick() { const url = "http://127.0.0.1:8000/parse" try { const response = await fetch(url, { // 移除no-cors模式 method: "POST", headers: { 'Content-type': 'application/x-www-form-urlencoded'}, body: new URLSearchParams({ locale: "en_GB", text: "Test Message" }) }); // 先检查请求是否成功(避免4xx/5xx状态码导致的错误) if (!response.ok) { throw new Error(`请求失败,状态码:${response.status}`); } data = await response.text(); console.log(data); // 现在可以正常打印服务器返回的数据了 } catch (error) { console.error('请求出错啦:', error); } }
方案2:使用代理服务器(无法修改后端时)
如果后端没法配置CORS,你可以在前端所在的服务器上搭建一个代理,让前端请求先发给代理,再由代理转发到目标服务器(服务器之间的请求不受浏览器同源策略限制)。
举个Node.js代理的示例(用http-proxy-middleware):
// 代理服务器代码(Node.js + Express) const express = require('express'); const { createProxyMiddleware } = require('http-proxy-middleware'); const app = express(); // 把/parse路径的请求转发到目标服务器 app.use('/parse', createProxyMiddleware({ target: 'http://127.0.0.1:8000', changeOrigin: true })); app.listen(3000, () => { console.log('代理服务器运行在http://localhost:3000'); });
然后把前端的请求地址改成http://localhost:3000/parse,这样就能绕过浏览器的同源限制,正常读取响应数据了。
补充说明
为什么网络面板能看到数据?因为浏览器本身会接收服务器的响应,但出于安全考虑,把这些内容对JavaScript代码隐藏了——所以你能在devtools里看到,但代码里拿不到。
内容的提问来源于stack exchange,提问作者rubyist

