当前位置: 首页 > news >正文

如何配置nginx解决前端跨域请求问题

我们以一个简单的例子模拟不同情况下产生的跨域问题以及解决方案。假设在http://127.0.0.1:8000的页面调用接口

fetch('http://127.0.0.1:8003/api/data')

常看到的错误“Access to fetch at ‘http://127.0.0.1:8003/api/data’ from origin ‘http://localhost:8000’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.”。这说明前端尝试访问的 API 服务,没有正确配置跨域资源共享(CORS)头。按如下配置:


server {listen 8003;server_name yourdomain.com;location / {# 允许所有来源访问(生产环境应限制为特定域名)add_header 'Access-Control-Allow-Origin' '*';# 允许的请求方法add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';     # 允许的请求头add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';# 预检请求(OPTIONS)缓存时间add_header 'Access-Control-Max-Age' 1728000;}
}

并重新加载配置nginx -s reload,问题解决。接下来,我们对请求参数做下修改,并重新发起请求:

var options = {method: 'GET', // 请求类型headers: {'Custom-Header': '123', // 自定义header参数}
}
fetch('http://127.0.0.1:8003/api/data',options)

Access to fetch at ‘http://127.0.0.1:8003/api/data’ from origin ‘http://localhost:8000’ 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.
HTTP 请求根据是否触发 CORS 预检(Preflight)分为 简单请求(Simple Request) 和 复杂请求(Complex Request)。它们的核心区别在于浏览器是否会先发送 OPTIONS 预检请求。 因为我们在请求头里增加了的参数Custom-Header,这样请求就从一个简单请求变成了复杂请求。上述错误显示预请求失败,我们重新修改nginx配置:


http {include       mime.types;default_type  application/octet-stream;map $http_origin $cors_origin {default "*";  # 默认值(如果 $http_origin 不存在)"~^https?://(localhost|example\.com|sub\.example\.com)(:[0-9]+)?$" $http_origin;"~^http?://(localhost|example\.com|sub\.example\.com)(:[0-9]+)?$" $http_origin;}server {listen       8003;server_name  localhost;location /api/data {add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';     add_header 'Access-Control-Allow-Credentials' 'true';add_header 'Access-Control-Max-Age' 1728000; # 预检缓存20天if ($request_method = 'OPTIONS') {add_header 'Access-Control-Allow-Origin' $cors_origin;add_header 'Access-Control-Allow-Credentials' 'true';add_header 'Access-Control-Max-Age' 1728000;add_header 'Content-Type' 'text/plain; charset=utf-8';add_header 'Content-Length' 0;return 204;}# 允许所有来源访问(生产环境应限制为特定域名)add_header 'Access-Control-Allow-Origin' '*';alias /Users/wk/data.json;default_type application/json;add_header Cache-Control "no-cache";}}

再发请求刚才的问题解决了,但又出现了新问题:
Access to fetch at ‘http://127.0.0.1:8003/api/data’ from origin ‘http://localhost:8000’ has been blocked by CORS policy: Request header field custom-header is not allowed by Access-Control-Allow-Headers in preflight response.”。
说明Access-Control-Allow-Headers不允许header里包含custom-header参数,需要在Access-Control-Allow-Headers里增加custom-header参数。注意Access-Control-Allow-Headers一定要放到if ($request_method = ‘OPTIONS’)语句内,否则不生效。因为CORS 配置的特殊要求,顺序尤为重要,预检请求(OPTIONS) 的响应头必须完整。

server {listen       8003;server_name  localhost;location /api/data {add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';     add_header 'Access-Control-Allow-Credentials' 'true';add_header 'Access-Control-Max-Age' 1728000; # 预检缓存20天if ($request_method = 'OPTIONS') {add_header 'Access-Control-Allow-Origin' $cors_origin;add_header 'Access-Control-Allow-Headers' 'Content-Type, Custom-Header,Authorization';add_header 'Access-Control-Allow-Credentials' 'true';add_header 'Access-Control-Max-Age' 1728000;add_header 'Content-Type' 'text/plain; charset=utf-8';add_header 'Content-Length' 0;return 204;}# 允许所有来源访问(生产环境应限制为特定域名)add_header 'Access-Control-Allow-Origin' '*';alias /Users/wk/data.json;default_type application/json;add_header Cache-Control "no-cache";}}

上述问题得以解决。我们再改下请求参数,增加 credentials: “include”。:


var options = {method: 'GET', // 请求类型credentials: "include",headers: {'Custom-Header': '123', // 自定义header参数'Content-Type': 'application/json' // 通常需要设置的内容类型}
}
fetch('http://127.0.0.1:8003/api/data',options)

credentials: “include” 的作用是:控制发送凭据,在跨域请求中携带当前域的 cookies、HTTP 认证头(如 Authorization)等敏感信息。但它有特殊要求,服务器需显式允许响应头包含 Access-Control-Allow-Credentials: true,Access-Control-Allow-Origin 不能为通配符 ,必须明确指定请求来源域名。否则就会错误类似的错误:
Access to fetch at ‘http://127.0.0.1:8003/api/data’ from origin ‘http://127.0.0.1:8000’ has been blocked by CORS policy: The value of the ‘Access-Control-Allow-Origin’ header in the response must not be the wildcard '
’ when the request’s credentials mode is ‘include’。
解决方法:

http {include       mime.types;default_type  application/octet-stream;map $http_origin $cors_origin {default "*";  # 默认值(如果 $http_origin 不存在)"~^https?://(localhost|example\.com|sub\.example\.com)(:[0-9]+)?$" $http_origin;"~^http?://(localhost|example\.com|sub\.example\.com)(:[0-9]+)?$" $http_origin;}server {listen       8003;server_name  localhost;location /api/data {add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';     add_header 'Access-Control-Allow-Origin' $cors_origin;add_header 'Access-Control-Max-Age' 1728000; # 预检缓存20天if ($request_method = 'OPTIONS') {add_header 'Access-Control-Allow-Origin' $cors_origin;add_header 'Access-Control-Allow-Headers' 'custom-header, content-type, authorization';add_header 'Access-Control-Allow-Credentials' 'true';add_header 'Access-Control-Max-Age' 1728000;add_header 'Content-Type' 'text/plain; charset=utf-8';add_header 'Content-Length' 0;return 204;}add_header 'Access-Control-Allow-Credentials' 'true';alias /Users/wk/data.json;default_type application/json;add_header Cache-Control "no-cache";}}

总结配置nginx支持跨域请求需要注意的几个要点

  1. 基础 CORS 头配置,必须返回的头部:
add_header 'Access-Control-Allow-Origin' '$http_origin';  # 或指定具体域名
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';  # 按需扩展
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';  # 包含客户端实际使用的头
Allow-Origin 不能同时使用 * 和 Allow-Credentials: true。
Allow-Methods 和 Allow-Headers 需明确列出(不能为 *)。
  1. 预检请求(OPTIONS)处理
if ($request_method = 'OPTIONS') {add_header 'Access-Control-Allow-Origin' '$http_origin';add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, OPTIONS';  # 与方法列表一致add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, X-Custom-Header';add_header 'Access-Control-Max-Age' 86400;  # 预检缓存时间(秒)return 204;  # 空响应
}
  1. 带凭据的请求(Credentials)
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Origin' $http_origin;  # 动态获取域名

Access-Control-Allow-Origin明确域名,不能用 *。Cookie 需设置 SameSite=None; Secur(HTTPS 环境)。

  1. 动态来源管理,使用 map 匹配合法来源:
map $http_origin $cors_origin {default "";"~^https://(www\.)?example\.com$" $http_origin;"~^http://localhost(:\d+)?$" $http_origin;
}
server {add_header 'Access-Control-Allow-Origin' $cors_origin;
}
http://www.xdnf.cn/news/896815.html

相关文章:

  • Nuxt.js 中的路由配置详解
  • (转)什么是DockerCompose?它有什么作用?
  • Ubuntu 基于sdl 音频学习的基础代码
  • 市面上哪款AI开源软件做ppt最好?
  • wordpress+woocommerce电商平台搭建方案的优势分析
  • 1.3 古典概型和几何概型
  • MySQL安装与配置详细讲解
  • vue3报错:SyntaxError: Identifier ‘__vite__injectQuery‘ has already been declared
  • PostgreSQL 技术峰会,聚焦国产生态与前沿技术
  • CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
  • 【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制
  • vue3:十五、管理员管理-页面搭建
  • Vue:Form正则校验
  • 数据库系统学习
  • 高效Excel合并拆分软件
  • Excel 发现此工作表中有一处或多处公式引用错误。请检查公式中的单元格引用、区域名称、已定义名称以及到其他工作簿的链接是否均正确无误。弹窗
  • Excel 模拟分析之单变量求解简单应用
  • 沙市区举办资本市场赋能培训会 点赋科技分享智能消费新实践
  • 【Go语言基础【5】】Go module概述:项目与依赖管理
  • go语言学习 第6章:错误处理
  • pgsql:还原数据库后出现重复序列导致“more than one owned sequence found“报错问题的解决
  • 正交多项式
  • 8K样本在DeepSeek-R1-7B模型上的复现效果
  • Java并发编程实战 Day 8:Java内存模型深度解析
  • c++第七天--特殊运算符的重载练习
  • Selenium自动下载浏览器驱动
  • 「Java教案」选择结构
  • Java并发编程实战 Day 10:原子操作类详解
  • AI变革思考2:当小众需求遇上人工智能,催生长尾应用的春天
  • Java编程课(一)