Fetch请求响应体无法解析为JSON但实际为有效JSON的问题排查
问题描述
我尝试通过以下TypeScript代码从WebService获取数据:
async function request(path: string, args: RequestInit | undefined): Promise<Response> { const headers: RequestInit = { mode: "no-cors" as RequestMode, headers: { 'Content-Type': 'application/json' } }; const url = `${ROOT_URL}/${path}?apiKey=${API_KEY}` const options = { ...args, ...headers, } const result = await fetch(url, options) return result; } try { const response = await request('my/endpoint', { method: 'GET', }) console.log('received response: ') console.log(response) const result = await response.json(); console.log(result) return Promise.resolve(result) } catch(error) { console.log('error:') console.log(error) return Promise.reject(error) }
发送请求后,控制台出现如下错误:
[Log] SyntaxError: The string did not match the expected pattern. — imagesSlice.ts:110 (bundle.js, line 633)
此外,响应对象的body字段为null,用await response.text()查看响应体返回空字符串。但通过curl请求该URL或直接在浏览器访问,响应体是经jsonlint验证有效的正确JSON。请问问题出在哪里?该如何调试?
问题原因与解决方法
核心问题:no-cors模式的限制
你设置了mode: "no-cors",这会触发浏览器的严格跨域限制:
- 浏览器确实会发起请求,但会完全禁止前端读取任何响应内容,不管后端返回的是什么,前端拿到的
Response都会是"不透明"的,表现为body为null、text()返回空字符串,调用json()自然会因为空字符串解析失败抛出语法错误。 - 这种模式仅适用于不需要读取响应的场景(比如请求第三方静态资源让浏览器缓存),完全不适合你需要读取JSON响应的需求。
解决步骤
移除
mode: "no-cors"配置
修改request函数里的headers对象,删掉mode属性:const headers: RequestInit = { headers: { 'Content-Type': 'application/json' } };此时浏览器会使用默认的
cors模式,这是跨域请求读取响应的正确模式。确保后端配置正确的CORS规则
移除no-cors后,浏览器会发起预检OPTIONS请求,后端需要在响应头中添加:Access-Control-Allow-Origin: 你的前端域名(生产环境不建议用*,避免安全风险)- 若请求携带自定义头或使用非GET/POST方法,还需配置
Access-Control-Allow-Headers、Access-Control-Allow-Methods等字段。
只有后端正确配置CORS,前端才能正常读取响应内容。
调试建议
- 查看Network面板:
在浏览器控制台的Network标签里,查看请求的状态码、响应头,确认:- 请求是否成功发送(状态码为200/201等)
- 响应头是否包含正确的CORS相关字段
- 响应预览栏是否能看到JSON内容(如果CORS配置正确,这里能看到,前端代码也能读取)
- 检查URL拼接正确性:
确认API_KEY是否存在、有没有特殊字符未编码,可使用encodeURIComponent(API_KEY)处理特殊字符 - 简化代码测试:
先写最基础的fetch请求排除封装问题:const testUrl = `${ROOT_URL}/my/endpoint?apiKey=${API_KEY}`; fetch(testUrl) .then(res => res.json()) .then(console.log) .catch(console.error);
内容的提问来源于stack exchange,提问作者sak
相关产品推荐
相关产品推荐

