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

React应用调用API遇CORS错误,Postman却可正常请求

问题背景

我有一个React应用,尝试向远程API发送POST请求,代码如下:

const App = () => {
  const [logData, setLogData] = useState([])

  const fetchUserData = () => {
    const username = 'logging-user';
    const password = 'password';
    const url = 'okstate';
    const authHeader = 'Basic ' + btoa(username + ':' + password);
    const requestOptions = {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': authHeader
      },
      body: JSON.stringify({ username, password, url })
    };
    fetch('url/get_logs', requestOptions)
      .then(response => response.json())
      .then(data => {
        setLogData(data)
      })
  }

  useEffect(() => {
    fetchUserData()
  }, [])

  return (
    <div>
      test
    </div>
  )
}

在浏览器中遇到CORS错误:

Access to fetch at 'url/get_logs' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

已知无法修改目标服务器,疑问是:为什么Postman配置相同的请求头和认证信息能正常获取数据,浏览器却不行?


原因解析

1. CORS是浏览器专属的安全机制

CORS(跨域资源共享)是浏览器为保护用户安全内置的限制策略,仅浏览器环境会触发这个检查。Postman、curl这类工具不属于浏览器沙盒环境,不受CORS规则约束,所以可以直接发送请求并接收响应。

2. 非简单请求的预请求差异

你的请求属于非简单请求:

  • 自定义了Authorization请求头
  • Content-Type为application/json(不属于简单请求允许的application/x-www-form-urlencoded、multipart/form-data、text/plain)

浏览器会对这类请求自动发送一个OPTIONS预请求,目的是询问服务器:是否允许当前源(http://localhost:3000)的请求?如果服务器没有返回Access-Control-Allow-Origin等必要的CORS响应头,浏览器就会拦截后续的POST请求,抛出你看到的错误。

而Postman不会发送这个预请求,直接发送POST请求,服务器收到后正常处理并返回数据,自然不会有问题。

3. 请求的Origin头差异

浏览器发送请求时会自动带上Origin头,值为当前页面的域名(http://localhost:3000),服务器会根据这个头判断是否允许跨域。但Postman默认不会添加Origin头,服务器没有收到这个触发CORS校验的标识,就不会执行跨域拦截逻辑,所以能正常响应。


可行的替代方案

因为无法修改目标服务器,你可以尝试以下方法绕过浏览器的CORS限制:

  • 本地代理:在React项目的package.json中添加"proxy": "目标API的根域名",比如"proxy": "https://example.com"。这样前端请求/get_logs时,会被自动转发到https://example.com/get_logs,代理请求不受CORS限制。
  • 浏览器调试插件:使用如Chrome的「Allow CORS: Access-Control-Allow-Origin」插件临时禁用CORS校验,仅适合开发调试,不能用于生产环境。
  • 自建中转服务:搭建一个简单的后端服务(比如Node.js/Express),前端请求自己的后端,后端再去调用目标API。服务器之间的HTTP请求不受CORS限制,后端拿到数据后再返回给前端。

内容的提问来源于stack exchange,提问作者Mark Locklear

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 18:22:43