1.跨域问题产生原因
跨域(Cross-Origin)问题,指的是浏览器的同源策略(Same-Origin Policy,SOP) 限制了从一个源(Origin)访问另一个源的资源。
游览器同源策略指的是(相同协议,相同地址,相同端口)
2.同源策略的目的
为了保护用户的数据安全,防止前端网站里面的恶意请求窃取用户数据。列子如下:
(1)当用户在登录一个如银行的网站后,会缓存在游览器一些cookie或会话信息
(2)之后用户如果进入一个钓鱼网站后,网站能获取到游览器的缓存信息,然后执行一些恶意请求的代码,用于获取用户的的隐私数据。如下:
javascript
fetch("https://bank.com/api/account", { credentials: "include" } //认证信息)
.then(res => res.json())
.then(data => console.log(data));
(3)游览器的同源策略就是为了防止这些恶意请求,从而进行拦截。除非在服务器通过配置CORS来允许这些请求。
3.解决同源策略的方式
1.通过webpack配置实现
原理:网站的请求通过webpack服务器代理向后端服务器发送数据请求,游览器只与webpack代理的服务器请求,从而避免了跨域请求。
2.通过nginx反向代理
同理也是通过nginx反向代理服务器转发请求到后端服务器,避免了游览器与后端服务器的通信。
小结:有了代理服务器后,浏览器从始至终都只与代理服务器交互,而不直接与后端服务器进行通信。

3.通过后端配置CORS
后端服务器配置CORS来告诉游览器那些请求源可以访问,让游览器不要拦截。
4.游览器拦截跨域请求的机制
- 简单请求(Simple Request)
对于某些简单的跨域请求(如 GET 或 POST 请求,且满足特定条件),浏览器会直接发送请求,但会在请求头中附加一个 Origin 字段,标明请求的来源。服务器收到请求后,需要检查 Origin 字段,并在响应头中包含 Access-Control-Allow-Origin,明确允许该来源访问。如果服务器没有返回这个响应头,或者 Access-Control-Allow-Origin 的值不匹配请求的 Origin,浏览器会拦截响应,不将其传递给前端代码。
- 预检请求(Preflight Request)
对于复杂的跨域请求(如使用了 PUT、DELETE 方法,或者请求头中包含自定义字段等),浏览器会先发送一个 OPTIONS 请求(即预检请求),询问服务器是否允许该跨域请求。这个预检请求会包含以下信息:
Origin:请求的来源。Access-Control-Request-Method:实际请求的方法(如PUT、DELETE等)。Access-Control-Request-Headers:实际请求中包含的自定义头。
服务器收到预检请求后,需要检查这些信息,并在响应头中返回:
Access-Control-Allow-Origin:允许的来源。Access-Control-Allow-Methods:允许的方法。Access-Control-Allow-Headers:允许的请求头。
w-Methods`:允许的方法。
Access-Control-Allow-Headers:允许的请求头。
如果服务器返回的响应头满足浏览器的要求,浏览器才会继续发送实际的跨域请求;否则,浏览器会直接拦截请求,不会发送实际请求。
5.通过nginx解决跨域问题两种方式
1.只加 CORS 响应头
js
server {
listen 80;
location /api/ {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
add_header Access-Control-Allow-Headers "Content-Type, Authorization";
if ($request_method = OPTIONS) {
return 204;
}
}
}
-
允许浏览器跨域访问
-
不转发请求
2.反向代理
server
listen 80;
location /api/ {
proxy_pass http://backend-server;
}
}
注意:前端调用API的baseURL必须和前端静项目域名同源