- 上一篇: Git WebHooks 配置教程
分类: Linux
Nginx跨域配置
Nginx 配置如下(server部分、location部分任选其一)
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header Access-Control-Allow-Origin "$http_origin";
add_header Access-Control-Allow-Credentials true;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
if ($request_method = 'OPTIONS') {
return 204;
}
如何理解反向代理?
Nginx是反向代理服务器,我们可以从下面的图来理解为什么是反向代理。以Nginx为中心,数据的流向是从Server到Nginx再到Client,注意这里说的是数据(响应数据),而不是请求。我们都知道水流一定是从上游流到下游,所以给Server一个别称上游服务器,当然这个别称并不是我定义的。
proxy_set_header和add_header的区别
区别: proxy_set_header是Nginx设置请求头信息给上游服务器,add_header是Nginx设置响应头信息给浏览器。
proxy_set_header
假如Nginx请求上游服务器时,添加额外的请求头,就需要使用proxy_set_header。在Java中使用HttpServletRequest#getHeader(String name)来获取请求头的值,name是请求头的名称。
例如:proxy_set_header X-Request-URI $scheme://$host/$uri;
String requestUrl = request.getHeader("X-Request-URI");
if (requestUrl == null) {
// 从Servlet服务器获取客户端请求地址
requestUrl = request.getRequestURL().toString();
}
add_header
Nginx响应数据时,要告诉浏览器一些头信息,就要使用add_header。例如跨域访问
add_header 'Access-Control-Allow-Origin' '*';
Nginx中的Host、X-Real-IP、X-Forwarded-For
客户端地址(请求服务的地址):192.168.1.1
Nignx服务器地址:192.168.1.2
后端服务器地址:192.168.1.3
X-Real-IP
是指客户端的真实IP,如果设置了$remote_addr这个值,后端服务器就能获取到客户端的真实IP,也就是此例中的192.168.1.1
Host
host的值设置为$proxy_host,是指proxy_pass中设置的host值,也就是192.168.1.3,也就是服务器的IP地址。
若客户端发过来的请求header中有HOST这个字段,$http_host和$host表示的就是原始请求host,比如请求的时候HOST的值是http://test.com,那么反代后还是http://test.com。
若客户端发过来的请求header中没有HOST这个字段,$host表示nginx代理服务器的地址,也就是此例中的192.168.1.2。
$http_host不是一个固定的变量,他其实是$http_HEADER通配后的结果,这里的HEADER是一个通配符,通配的是请求头里的header属性,例如$http_content_type表示请求头里content-type属性的值,同理,$http_host指的就是请求头里的host属性。
X-Forwarded-For
这个变量的值有$proxy_add_x_forwarded_for和$remote_addr,在只有一个代理服务器的转发的情况下,两者的效果貌似差不多,都可以真实的显示出客户端原始ip。
举例说明,用户A的IP是192.168.1.1,请求一个经过两次nginx转发的应用,在第一台nginx中(192.168.1.2),配置如下:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
现在$proxy_add_x_forwarded_for变量的"X-Forwarded-For"部分是空的,所以只有$remote_addr,而$remote_addr的值是用户的ip,那么X-Forwarded-For变量的值就是用户的ip:192.168.1.1。
到第二台nginx,配置如下:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
现在的$proxy_add_x_forwarded_for变量,X-Forwarded-For部分包含的是用户的真实ip,$remote_addr部分的值是上一台nginx的ip地址,那么X-Forwarded-For的值就变成了"用户的真实ip,第一台nginx的ip",也就是“192.168.1.1,192.168.1.2”
所以还是建议X-Forwarded-For的值设置成$proxy_add_x_forwarded_for。
跨域头设置
Access-Control-Allow-Origin
响应头指定了该响应的资源是否被允许与给定的origin共享。
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
Access-Control-Allow-Credentials
响应头表示是否可以将对请求的响应暴露给页面。返回true则可以,其他值均不可以。 Credentials可以是 cookies, authorization headers 或 TLS client certificates。
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials
Access-Control-Allow-Methods
在对 preflight request.(预检请求)的应答中明确了客户端所要访问的资源允许使用的方法或方法列表。
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Access-Control-Allow-Methods
Access-Control-Allow-Headers
用于 preflight request (预检请求)中,列出了将会在正式请求的 Access-Control-Request-Headers 字段中出现的首部信息。
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Access-Control-Allow-Headers
OPTIONS请求
HTTP 的 OPTIONS 方法 用于获取目的资源所支持的通信选项。在CORS中,当HTTP请求为复杂请求时,会发起OPTIONS预检请求。
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods/OPTIONS
简单请求和复杂请求
简单请求
满足以下条件的请求即为简单请求:请求方法:GET、POST、HEAD
除了以下的请求头字段之外,没有自定义的请求头
- Accept
- Accept-Language
- Content-Language
- Content-Type
- DPR
- Downlink
- Save-Data
- Viewport-Width
- Width
- Content-Type 的值只有以下三种(Content-Type一般是指在post请求中,get请求中设置没有实际意义) text/plain、multipart/form-data、application/x-www-form-urlencoded
请求中的任意XMLHttpRequestUpload 对象均没有注册任何事件监听器 (未验证)
XMLHttpRequestUpload 对象可以使用 XMLHttpRequest.upload 属性访问
请求中没有使用 ReadableStream 对象 (未验证)
复杂请求
非简单请求即为复杂请求。复杂请求我们也可以称之为在实际进行请求之前,需要发起预检请求的请求。
附带身份凭证的请求
一般而言,对于跨域 XMLHttpRequest或 Fetch 请求,浏览器不会发送身份凭证信息。如果要发送凭证信息,需要设置 XMLHttpRequest 的某个特殊标志位。
如果在发送请求的时候,给xhr 设置了withCredentials为true,从而向服务器发送 Cookies,如果服务端需要想客户端也发送cookie的情况,需要服务器端也返回Access-Control-Allow-Credentials: true响应头信息。
对于附带身份凭证的请求,服务器不得设置 Access-Control-Allow-Origin的值为“*”。
这是因为请求的首部中携带了Cookie信息,如果 Access-Control-Allow-Origin的值为“*”,请求将会失败。而将 Access-Control-Allow-Origin的值设置为 http://foo.example(请求源),则请求将成功执行。
本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:http://zhupeixin.com/article/2021/07/cors
( 本篇完 )
- 下一篇: Centos 安装Nginx+Node