nginx跨域訪問配置的幾種方法實現
一、基本跨域配置
在 nginx 的 location 塊中添加以下內容:
location /api/ {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept, Authorization' always;
# 處理預檢請求(OPTIONS)
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
# 其他反向代理/靜態(tài)資源配置...
proxy_pass http://backend-server;
}說明:
Access-Control-Allow-Origin:允許哪些域訪問,*表示所有域。Access-Control-Allow-Methods:允許的 HTTP 方法。Access-Control-Allow-Headers:允許的請求頭。OPTIONS方法用于處理 CORS 預檢請求,返回 204 No Content。
二、只允許指定域名跨域
如果只允許某個域(如 https://www.example.com)跨域:
add_header 'Access-Control-Allow-Origin' 'https://www.example.com' always;
三、完整示例
假設你有一個前端(端口 8080)和后端(端口 8000),nginx 代理 /api/ 到后端:
server {
listen 80;
server_name your.domain.com;
location /api/ {
proxy_pass http://127.0.0.1:8000;
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept, Authorization' always;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
}
}四、配置后重載 nginx
每次修改配置后,記得重載 nginx:
nginx -s reload
五、注意事項
- 如果后端也設置了 CORS,可能會有沖突,建議只在一個地方設置。
- 如果需要攜帶 cookie,
Access-Control-Allow-Origin不能為*,必須指定具體域名,并加上Access-Control-Allow-Credentials: true。
六、支持攜帶 Cookie 的跨域配置
如果你需要前端跨域請求時攜帶 cookie(如登錄態(tài)),CORS 需要特殊配置:
- Access-Control-Allow-Origin 不能為
*,必須指定具體的域名。 - 需要加上
Access-Control-Allow-Credentials: true。
示例:
location /api/ {
proxy_pass http://127.0.0.1:8000;
add_header 'Access-Control-Allow-Origin' 'https://www.example.com' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept, Authorization' always;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
}前端請求時需要設置:
fetch('https://api.example.com/api/', {
credentials: 'include', // 允許攜帶 cookie
// 其他參數
})七、根據請求頭動態(tài)設置允許的 Origin
有時你希望根據請求頭 Origin 動態(tài)設置允許的域名,可以用 nginx 的變量:
location /api/ {
proxy_pass http://127.0.0.1:8000;
if ($http_origin ~* "^https://(www\.example\.com|other\.domain\.com)$") {
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
}
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept, Authorization' always;
# 處理預檢請求
if ($request_method = 'OPTIONS') {
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 不生效?
- 確認
always關鍵字已加上。 - 確認沒有被其他配置覆蓋。
- 確認 location 塊沒有被其他 server/location 塊覆蓋。
- 確認
OPTIONS 請求未返回 204?
- 檢查 if 語句是否正確。
- 檢查是否被后端攔截。
前端報錯:CORS header ‘Access-Control-Allow-Origin’ missing?
- 檢查響應頭是否包含該字段。
- 用瀏覽器開發(fā)者工具 Network 檢查響應頭。
攜帶 cookie 時跨域失???
- 確認
Access-Control-Allow-Origin不是*,而是具體域名。 - 確認
Access-Control-Allow-Credentials: true已設置。 - 前端 fetch/axios 需配置 credentials。
- 確認
九、nginx 跨域配置模板(推薦)
可以將以下內容作為通用模板:
location /api/ {
proxy_pass http://backend-server;
# 支持跨域
set $cors '';
if ($http_origin ~* '^https://(www\.example\.com|other\.domain\.com)$') {
set $cors 'true';
}
if ($cors = 'true') {
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
}
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept, Authorization' always;
# 預檢處理
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
}十、針對不同路徑/接口做跨域控制
有時你只希望對部分接口(如 /api/)開放跨域,對其他接口(如 /admin/)不開放,可以這樣配置:
server {
listen 80;
server_name your.domain.com;
# 只對 /api/ 開放跨域
location /api/ {
proxy_pass http://backend-api;
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept, Authorization' always;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
}
# /admin/ 不開放跨域
location /admin/ {
proxy_pass http://backend-admin;
# 不添加跨域相關 header
}
}十一、靜態(tài)資源跨域(如圖片、字體、JS/CSS)
如果你希望靜態(tài)資源(如圖片、字體文件等)可以被其他域引用,需為靜態(tài)資源 location 添加 CORS 響應頭:
location /static/ {
root /var/www/html;
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept' always;
}注意:如果你希望字體文件可被第三方引用,必須加上 Access-Control-Allow-Origin,否則會有跨域問題。
十二、根據請求方法細分 CORS 策略
有時你希望 GET/POST/PUT/DELETE 允許跨域,而 PATCH 不允許,可以這樣寫:
location /api/ {
proxy_pass http://backend-server;
if ($request_method ~* "GET|POST|PUT|DELETE|OPTIONS") {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept, Authorization' always;
}
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
}十三、反向代理多后端的跨域配置
如果 nginx 代理多個后端(如 /api1/、/api2/),每個后端都需要跨域:
location /api1/ {
proxy_pass http://backend1;
add_header 'Access-Control-Allow-Origin' '*' always;
# ...同上
}
location /api2/ {
proxy_pass http://backend2;
add_header 'Access-Control-Allow-Origin' '*' always;
# ...同上
}十四、nginx 1.7.5 及以上版本的 always 參數
確保你用的 nginx 版本支持 always 參數,否則有些 header 在 4xx/5xx 狀態(tài)下不會返回。
十五、安全建議
- 生產環(huán)境不要使用 *,要指定具體域名。
- 不建議在 / 根路徑全局添加 CORS,容易引發(fā)安全隱患。
- 如需支持多域名跨域,推薦用變量和正則動態(tài)判斷。
- 如果接口涉及敏感數據,務必開啟認證和 HTTPS。
十六、調試技巧
- 用 Chrome/Firefox 開發(fā)者工具的 Network 面板查看 Response Headers,確認 CORS 頭是否正確返回。
- 使用
curl -i命令直接發(fā)起跨域請求,檢查響應頭。 - 檢查 nginx 日志(access.log 和 error.log)排查問題。
十七、完整多場景配置模板
server {
listen 80;
server_name your.domain.com;
# 靜態(tài)資源
location /static/ {
root /var/www/html;
add_header 'Access-Control-Allow-Origin' '*' always;
}
# API1 跨域
location /api1/ {
proxy_pass http://backend1;
add_header 'Access-Control-Allow-Origin' 'https://www.a.com' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept, Authorization' always;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
}
# API2 跨域
location /api2/ {
proxy_pass http://backend2;
add_header 'Access-Control-Allow-Origin' 'https://www.b.com' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept, Authorization' always;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
}
}到此這篇關于nginx跨域訪問配置的幾種方法實現的文章就介紹到這了,更多相關nginx跨域訪問配置內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
nginx中的兩個模塊的proxy_pass的區(qū)別解析
在nginx中配置proxy_pass代理轉發(fā)時,如果在proxy_pass后面的url加/,表示絕對根路徑;如果沒有/,表示相對路徑,把匹配的路徑部分也給代理走。本文給大家介紹nginx中的兩個模塊的proxy_pass的區(qū)別,感興趣的朋友一起看看吧2021-11-11

