00_跨域的概念

浏览器只允许请问具有相同的协议,域名,端口,进行请求,有一个不同,就会拒绝。
01.前后端协商jsonp
//jsonp
//jsonp 是 json with padding 的缩写,是一种通过 <script> 标签的 src 属性来实现跨域请求的技术。
//jsonp 的原理是利用 <script> 标签的 src 属性可以加载外部资源,并且不受同源策略的限制,
//所以可以通过 <script> 标签的 src 属性来加载外部资源,实从而现跨域请求。
//jsonp 的缺点是只能发送 get 请求,不能发送 post 请求。
//jsonp 的优点是简单易用,不需要服务器端的支持,只需要在客户端实现即可。
只能发送get请求
后端

前端
(通过挂载全局函数解决)

02_前端解决,使用代理dev
直接请求,有跨域问题


解决方案:使用打包构建工具:vite或者webpack解决

import { defineConfig } from 'vite';
export default defineConfig({
server: {
proxy: {
// 将 /api 开头的请求代理到 Node.js 服务器
'/api': {
target: 'http://localhost:3000',
changeOrigin: true
}
}
}
});

03.后端解决,设置请求头
直接在接口处使用cors插件也行,设置请求头允许所有源访问。
前端

后端


nginx反向代理配置
将前端请求代理到后端API,例如:
nginx
server {
listen 80;
server_name localhost;
location /api {
proxy_pass http://api.example.com;
}
}
2. 添加跨域响应头
在代理配置中设置CORS相关头信息:
nginx
location /api {
proxy_pass http://api.example.com;
# 允许的请求来源(替换为你的前端域名)
add_header 'Access-Control-Allow-Origin' 'http://localhost:8080' always;
# 允许的HTTP方法
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
# 允许的请求头
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization' always;
# 允许携带凭证(如cookies)
add_header 'Access-Control-Allow-Credentials' 'true' always;
}
always
参数确保即使后端返回4xx/5xx错误,头信息仍被添加。
3. 处理OPTIONS预检请求
针对OPTIONS
方法单独处理,直接响应无需转发到后端:
nginx
location /api {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'http://localhost:8080';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
add_header 'Access-Control-Max-Age' 1728000; # 缓存预检结果20天(秒)
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
proxy_pass http://api.example.com;
# ... 其他头配置同上
}
4. 动态允许多域名(可选)
使用map
模块动态匹配允许的域名:
nginx
map $http_origin $cors_origin {
default "";
~^https?://(localhost:8080|example\.com|app\.example\.net)$ $http_origin;
}
server {
...
location /api {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' $cors_origin;
...
return 204;
}
proxy_pass http://api.example.com;
add_header 'Access-Control-Allow-Origin' $cors_origin always;
...
}
}
5. 完整配置示例
nginx
http {
map $http_origin $cors_origin {
default "";
~^https?://(localhost:8080|example\.com)$ $http_origin;
}
server {
listen 80;
server_name localhost;
location /api {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' $cors_origin;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
proxy_pass http://api.example.com;
add_header 'Access-Control-Allow-Origin' $cors_origin always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
}
}
}
6. 关键注意事项
-
安全性 :避免使用
*
作为Access-Control-Allow-Origin
的值,明确指定可信域名。 -
凭证携带 :若前端需要发送Cookies,设置
Access-Control-Allow-Credentials: true
,且Access-Control-Allow-Origin
不能为*
。 -
缓存预检 :合理设置
Access-Control-Max-Age
减少OPTIONS请求次数。 -
测试验证 :使用浏览器开发者工具或
curl
检查响应头是否包含CORS头信息。
验证命令示例
curl -I -X OPTIONS http://nginx-server/api
# 检查返回头中是否包含CORS相关字段
更详细的可以访问:nginx跨域解决