nginx 代理实现跨域的原理(CORS跨域访问原理和Nginx配置)
nginx 代理实现跨域的原理(CORS跨域访问原理和Nginx配置)1.请求方法是以下三种方法之一: HEAD GET POST 2.HTTP的头信息不超出以下几种字段: Accept Accept-Language Content-Language Last-Event-ID Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain 凡是不同时满足上面两个条件,就属于非简单请求。只要同时满足以下两大条件,就属于简单请求CORS分类浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)一、简单请求
CORS简介
CORS是一个W3C标准,全称是跨域资源共享(Cross-origin resource sharing)。它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
简单来说就是跨域的目标服务器要返回一系列的Headers,通过这些Headers来控制是否同意跨域。 CORS提供的Headers,在Request包和Response包中都有一部分:
#服务端 HTTP Response Header Access-Control-Allow-Origin Access-Control-Allow-Credentials Access-Control-Allow-Methods Access-Control-Allow-Headers Access-Control-Expose-Headers Access-Control-Max-Age #请求客户端 HTTP Request Header Access-Control-Request-Method Access-Control-Request-Headers
其中Access-Control-Allow-Headers一般包含基本字段,如Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma;对于其他字段,就必须在Access-Control-Expose-Headers里面指定。
CORS分类
浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)
一、简单请求
只要同时满足以下两大条件,就属于简单请求
1.请求方法是以下三种方法之一: HEAD GET POST 2.HTTP的头信息不超出以下几种字段: Accept Accept-Language Content-Language Last-Event-ID Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
凡是不同时满足上面两个条件,就属于非简单请求。
二、非简单请求
非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUT、DELETE或OPTIONS,或者Content-Type字段的类型是application/json。
跨域处理方式
浏览器对简单请求和非简单请求这两种请求的处理是不一样的。
1.简单请求
对于简单请求,浏览器直接发出CORS请求。具体来说,就是在头信息之中,增加一个Origin字段。 处理如下:
add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET POST OPTIONS PUT DELETE'; add_header 'Access-Control-Allow-Headers' 'Content-Type';
在nginx上经以上配置,一般能够解决简单请求的跨域处理。 CORS请求默认不发送Cookie和HTTP认证信息。但是如果要把Cookie发到服务器,要服务器同意,指定Access-Control-Allow-Credentials字段。
add_header 'Access-Control-Allow-Credentials' 'true';
需要注意的是,如果要发送Cookie,Access-Control-Allow-Origin就不能设为星号,必须指定明确的、与请求网页一致的域名。
2.非简单请求
非简单请求的CORS请求会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight), 预捡的请求方法是OPTIONS 。
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。 因此我们可以在浏览器的开发者工具中查看头信息,若头信息中有OPTIONS方法,说明此次CORS请求是非简单请求,需要在nginx中添加头:
add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET POST OPTIONS PUT DELETE'; add_header 'Access-Control-Allow-Headers' 'Content-Type';
此时虽然我们已经添加了所有的Methods方法,但是预检请求仍不会通过,因此此时nginx对OPTIONS方法返回"405 Method Not Allowed"或者403。
nginx配置CORS
基于前面的分析,nginx配置如下:
假设对于/api路径的CORS请求都路由到本地的7000 web服务器端口:
location ~ /api/ { add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods 'GET POST OPTIONS'; add_header Access-Control-Allow-Headers 'x-requested-with Authorization Content-Type access-control-allow-origin'; if ($request_method = 'OPTIONS') { return 200; } proxy_pass http://localhost:7000; }
nginx将prelight的OPTIONS方法返回200,然后浏览器会再次发起一个正常的请求
详情:https://www.lvbby.com/p/md/1901281715042812789002