nginx跨域配置
- 参考文档
- location总结
- 跨域配置
- nginx跨域方式
- 配置文件
location总结
location | 介绍 |
location = /uri | 严格匹配。如果这个查询匹配,那么将停止搜索并立即处理此请求。 |
location ~ pattern | 正则表达式匹配,正则表达式必定以~开头 |
location ~* pattern | 正则匹配 不区分大小写的 |
location ^~ /uri | 对url路径进行前缀匹配,在正则之前,成功则不测试其他正则 |
location /url | 前缀普通匹配,在正则之后 |
location / | 通用匹配 |
优先级: "精确匹配 = > 特殊前缀匹配 ^~ > 正则匹配 ~ > 普通匹配 > 通用匹配 / "
^~ 和 ~ 路径相同的话 nginx会报错
普通匹配:顺序无所谓,是因为按命中长短来确定的
正则匹配:顺序有所谓,因为是从前往后命中的
跨域配置
可配置在 http, server, location, if in location,建议配置在http中,以免多次重复配置
add_header意思是在http response中添加头部信息 发生在接口响应完成后
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Origin' $http_origin;
#想要额外暴露自定义的首部,特定时候需要
#add_header 'Access-Control-Expose-Headers' 'TOKEN';
add_header 'Access-Control-Allow-Methods' 'GET,POST,PUT,DELETE,OPTIONS,PATCH';
#注意:后端如果使用认证的key 是token,则下面需要加入token 如果是Authorization 则加入Authorization,如果是其他,添加对应即可
add_header 'Access-Control-Allow-Headers' 'content-type,token,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,x_requested_with';
nginx跨域方式
- 方式1:不跨域 前后端配置在一个server中
前端baseUrl=http://localhost/api
ip端口都相同,无需跨域,不需要http中跨域配置
location ^~ /api {
proxy_pass http://localhost:8081;
}
#前端页面文件请求
location / {
root /data/project/dist;
}
- 方式2:跨端口,域名ip相同,端口不同
前端baseUrl=http://localhost:8088/api
无需添加option请求处理,http中跨域生效
server {
listen 8088;
server_name localhost;
location ^~ /api {
proxy_pass http://localhost:8081;
}
}
- 方式3:跨ip或域名,域名不同,端口相同
前端baseUrl=http://test.cn/api 需要添加option请求处理
否则控制台提示It does not have HTTP ok status
server {
listen 80;
server_name test.cn;
location ^~ /api {
if ($request_method = 'OPTIONS') {
return 204;
}
proxy_pass http://localhost:8081;
}
}
- 方式4:跨ip域名端口
前端baseUrl=http://test.cn:8088/api
需要添加option请求处理
未添加时,日志分析出收到了option请求,但是Nginx返回了403,控制台报错,未添加跨域头
server {
listen 8088;
server_name test.cn;
location ^~ /api {
if ($request_method = 'OPTIONS') {
return 204;
}
proxy_pass http://localhost:8081;
}
}
配置文件
#user nobody;
worker_processes 1;
error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
#default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on; # 二选一,不缓存压缩后的文件
#gzip_static on; #二选一,需要配置模块,会缓存压缩后的文件
#gzip_disable "msie6"; #不使用gzip IE6
#gzip_min_length 1k; #gzip压缩最小文件大小,超出进行压缩(自行调节)
#gzip_buffers 4 16k; #buffer 不用修改
#gzip_comp_level 8; #压缩级别:1-10,数字越大压缩的越好,时间也越长
#gzip_types text/plain application/x-javascript text/css application/xml text/javascript image/jpeg image/gif image/png; # 压缩文件类型
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Cookie $http_cookie;
#跨域配置
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Origin' $http_origin;
#想要额外暴露自定义的首部,特定时候需要
#add_header 'Access-Control-Expose-Headers' 'TOKEN';
add_header 'Access-Control-Allow-Methods' 'GET,POST,PUT,DELETE,OPTIONS,PATCH';
#后端如果使用认证的key 是token,则下面需要添加token 如果是Authorization 则添加Authorization即可
add_header 'Access-Control-Allow-Headers' 'content-type,token,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,x_requested_with';
# 常见问题 502后台服务挂了 404 首页正常的话一般配置问题 302 403配置问题
# 参考文档 官方文档:http://nginx.org/en/docs/
# http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
# http://nginx.org/en/docs/http/ngx_http_headers_module.html
# location = /uri 严格匹配。如果这个查询匹配,那么将停止搜索并立即处理此请求。
# location ~ pattern 正则表达式匹配,正则表达式必定以~开头,
# 例子location ~ \.(gif|jpg|png)$ 正则知识: '\.'表示转义后的'.' '|'表示或 #'$'表示截止 ,如果.png后面还有字符则匹配失败
# location ~* pattern 不区分大小写的正则匹配
# location ^~ /uri 对url路径进行前缀匹配,在正则之前,成功则不测试其他正则
# location /url 前缀匹配,在正则之后
# location / 通用匹配
# 优先级: 精确匹配= > 特殊前缀匹配^~ > 正则匹配~ > 普通匹配 > 通用匹配/
# ^~ 和 ~ 路径相同的话 nginx会报错
# 普通匹配:顺序无所谓,是因为按命中长短来确定的
# 正则匹配:顺序有所谓,因为是从前往后命中的
server {
listen 80;
server_name localhost;
charset utf-8;
access_log logs/nginx_access.log main; # 成功日志
error_log logs/nginx_error.log error; # 错误日志
index index.html index.htm;
# 变量设置,设置公共路径
set $root D:/build/;
#方式1:不跨域
# 前端baseUrl=http://localhost/api
# ip端口都相同,无需跨域,不需要上述http中跨域配置
location ^~ /api {
proxy_pass http://localhost:8081;
}
#前端页面文件请求
location / {
root $root;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
# 以下全是后台服务配置
# 方式2:跨端口,域名ip相同,端口不同
# 前端baseUrl=http://localhost:8088/api
# 无需添加option请求处理,http中跨域生效
server {
listen 8088;
server_name localhost;
#如果api 改为 api/ 则请求地址必须追加/
location ^~ /api {
proxy_pass http://localhost:8081;
}
}
# 方式3:跨ip或域名,域名不同,端口相同
# 前端baseUrl=http://test.cn/api 需要添加option请求处理
# 否则控制台提示It does not have HTTP ok status
server {
listen 80;
server_name test.cn;
location ^~ /api {
if ($request_method = 'OPTIONS') {
return 204;
}
proxy_pass http://localhost:8081;
}
}
# 方式4:跨ip域名端口
# 前端baseUrl=http://test.cn:8088/api
# 需要添加option请求处理
# 未添加时,日志分析出收到了option请求,但是Nginx返回了403,控制台报错,未添加跨域头
server {
listen 8088;
server_name test.cn;
location ^~ /api {
if ($request_method = 'OPTIONS') {
return 204;
}
proxy_pass http://localhost:8081;
}
}
}
文章为个人经验总结,有不对的地方欢迎指正