You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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响应的需求。

解决步骤

  1. 移除mode: "no-cors"配置
    修改request函数里的headers对象,删掉mode属性:

    const headers: RequestInit = {
        headers: {
            'Content-Type': 'application/json'
        }
    };
    

    此时浏览器会使用默认的cors模式,这是跨域请求读取响应的正确模式。

  2. 确保后端配置正确的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 09:13:23