跨域问题-1
如今的 Web 项目大多采用前后端分离架构,这使得跨域问题变得常见。
CORS (Cross-Origin Resource Sharing) 跨域资源共享,是浏览器的安全机制。当前端(如 http://localhost:3000)请求后端(如 http://localhost:5000)时,因为域名/端口不同,浏览器会阻止请求,除非后端明确允许。
跨域问题有哪些现象
如果出现跨域问题:
- 前端:浏览器正在访问一个页面
https://www.helloworld.net/special, 此页面中发送了一个后端的一个 http 接口 - 后端:访问的后端接口为:
https://tiger-api.helloworld.net/v1/special/getSpecialList
提示:has been blocked by CORS policy: Response to preflight request does not pass access control check
翻译过来就是:已被 CORS 策略阻止:对请求的响应未通过访问控制检查
如果没有配置相关的跨域参数,是不能访问这个接口。
什么是跨域问题
如果浏览器访问: https://www.helloworld.net/special
在此页面中,可以请求接口:https://www.helloworld.net/getSpecialList
它们的协议、主机和端口都是相同的,是可以请求成功的。否则,不可以访问。
注意:是在浏览器中
同源策略保证,协议、主机、端口完全相同,才可以互相访问。否则只要有一个不同,是不能访问的。

如何解决跨域问题
通过上面的图,浏览器拦截了响应,导致整个 http 请求没有走通。
如果在响应头中添加一些特殊的字段,浏览器看到这些字段,就不拦截了,跨域问题就解决了。
解决跨域问题,就是在后端加一些配置,在响应头中添加了一些特殊的响应头。

只要后端在响应的时候,在响应头添加以下字段,就可以解决跨域问题:
access-control-allow-orign:该字段是必须的。它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。access-control-allow-credentials:该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可Access-Control-Allow-Methods:该字段必需,它的值是逗号分隔的一个字符串,表明服务器支持的所有跨域请求的方法。注意,返回的是所有支持的方法,而不单是浏览器请求的那个方法。这是为了避免多次”预检”请求。
其实最重要的就是 access-control-allow-origin 字段,添加一个 * ,允许所有的域都能访问。
实践案例
环境变量配置(.env)
1 | # 开发环境 |
后端 CORS 中间件配置
1 | const cors = require('cors'); |
配置说明
| 配置项 | 说明 | 常用值 |
|---|---|---|
origin |
允许的来源 | 函数动态判断或字符串 |
credentials |
是否允许携带凭证 | true/false |
methods |
允许的 HTTP 方法 | ['GET', 'POST', ...] |
allowedHeaders |
允许的请求头 | ['Content-Type', ...] |
exposedHeaders |
前端可访问的响应头 | ['X-Total-Count'] |
maxAge |
预检缓存时间(秒) | 86400 |
前端配置
1 | fetch('http://localhost:5000/api/data', { |
常见问题
Q:localhost 和 127.0.0.1 需要分别配置吗?
A: 是的,浏览器认为它们是不同的源,都需要添加到白名单。
Q: 为什么 Postman 能访问但浏览器不行?
A: Postman 不受同源策略限制,浏览器会强制执行 CORS 检查。
Q: 配置了 CORS 但还是报错?
A: 检查:
- 前端请求是否包含
credentials: 'include'或withCredentials: true - 后端是否设置
credentials: true - Origin 是否完全匹配(包括协议、端口)
- 是否正确处理 OPTIONS 预检请求
总结
- 同源策略:协议,主机,端口 三者都相同,就是同一个源,只要有一个不同,就是不同的源,只有同一个源的资源才能互相访问
- 跨域问题就是浏览器的同源策略造成的
- 跨域问题的本质 ,就是浏览器拦截了响应,所以后端只需要在响应头中添加相应的字段,就可以解决跨域问题


