一.跨域出现原因
跨域是指a页面想获取b页面资源,如果a、b页面的协议、域名、端口、子域名不同,或是a页面为ip地址,b页面为域名地址,所进行的访问行动都是跨域的,而浏览器为了安全问题一般都限制了跨域访问,也就是不允许跨域请求资源。
跨域问题的根本原因:因为浏览器收到同源策略的限制,当前域名的js只能读取同域下的窗口属性。什么叫做同源策略?就是不同的域名, 不同端口, 不同的协议不允许共享资源的,保障浏览器安全。同源策略是针对浏览器设置的门槛。
只有访问类型为XHR(XMLHttpRequest)的才会出现跨域。XHR是基于XML的HTTP请求,XHR用于在后台与服务器交换数据。XHR是一个浏览器接口,使得Javascript可以进行HTTP(S)通信,ajax就是基于浏览器提供的XHR对象来实现的。ajax,可以实现异步的加载网页也就是说可以在不重新加载整个网页的情况下,对网页的某部分进行更新。浏览器端发送的请求只有XHR 或 fetch 发出的才是 ajax 请求, 其它所有的都是非 ajax 请求,ajax 请求是一种特别的 http 请求。当浏览器端接收到ajax 请求,浏览器不会对界面进行任何更新操作, 只是调用监视的回调函数并传入响应相关数据。
二.跨域的解决策略
CORS是跨源资源分享(Cross-Origin Resource Sharing)的缩写。它是W3C标准,是跨源AJAX请求的根本解决方法。相比JSONP只能发GET请求,CORS允许任何类型的请求。CORS为Web服务器定义了一种方式,允许网页从不同的域访问其资源。而这种访问是被同源策略所禁止的。CORS系统定义了一种浏览器和服务器交互的方式来确定是否允许跨域请求。 CORS实现了AJAX可控的跨域访问。
在nginx中添加跨域配置,可以添加在server字段,应用于整个server,也可以添加在server:location字段下,应用于单个location。当前层级无 add_header 指令时,则继承上一层级的add_header。相反的若当前层级有了add_header,就无法继承上一层的add_header。
# 指定允许的请求域名端口访问我们的跨域资源,*代表所有的域,也可设置具体方法
# add_header Access-Control-Allow-Origin *;
#当带cookie访问时不能用*,带cookie的请求不支持*号。$http_origin表示动态获取请求客户端请求的域。
add_header Access-Control-Allow-Origin $http_origin;
# 带cookie请求需要加上这个字段,并设置为true
add_header Access-Control-Allow-Credentials true;
# 指定允许跨域的方法,*代表所有方法,$http_access_control_request_method指动态获取,也可设置具体方法。
# add_header Access-Control-Allow-Methods $http_access_control_request_method;
#如设置GET,POST,OPTIONS三种方法
add header Access-Control-Allow-Methods 'GET, POST, OPTIOS';
# 表示请求头的字段,*表示所有字段
#add_header Access-Control-Allow-Headers *;
#动态获取
add_header Access-Control-Allow-Headers $http_access_control_request_headers;
# 预检命令的缓存,如果不缓存每次会发送两次请求
add_header Access-Control-Max-Age 3600;
# OPTIONS预检命令,预检命令通过时才发送请求
# 检查请求的类型是不是预检命令
if ($request_method = OPTIONS){
return 200;
}