跨域
什么是跨域?
跨域是由于浏览器的同源策略产生的,所谓同源策略,需要 URL
的协议(如 http
)、域名和端口号一致,才是同源的,浏览器默认同源网页可以互相访问资源与 DOM
操作,非同源之间无法操作。
非同源的页面之间:
- 无法访问与操作对方的
DOM
;- 浏览器提供了
window.postMessage
方法实现不同源页面之间的消息通知
- 浏览器提供了
- 本地存储(如
cookie、storage
等)无法共用; - 接口请求限制;
CORS
允许浏览器向跨源服务器发送 ajax
请求
CORS 请求分为两类:
简单请求
简单请求主要三种方法:HEAD
、GET
、POST
,对应的请求 header
的 Content-Type
只能是 application/x-www-form-urlencoded
、multipart/form-data
、text/plain
三种,不能是 json
非简单请求
除以上情况外的请求就是非简单请求,如 PUT
、DELETE
, header
的 Content-Type
是 application/json
等情况,当前浏览器发现发送的请求为非简单请求时,会先发出预检(OPTIONS
)请求,询问服务器是否支持该请求。
服务器收到 OPTIONS
请求以后,会检查 Origin
、Access-Control-Request-Method
和 Access-Control-Request-Headers
字段是否支持,确认允许跨源请求,就可以做出回应。
问题
1. 为什么会存在跨域?
浏览器的同源策略限制。
2. 有哪些解决方案?
2.1 Nginx
反向代理
SHELL
server {
listen 80;
server_name www.xxx.com;
location /api/ {
proxy_pass http://www.demo.com; # 服务器接口地址
}
}
server {
listen 80;
server_name www.xxx.com;
location /api/ {
proxy_pass http://www.demo.com; # 服务器接口地址
}
}
2.2 Nginx
添加允许请求头白名单
SHELL
http {
...
add_header Access-Control-Allow-Origin * always;
# add_header Access-Control-Allow-Origin 'http://www.demo.com';
...
}
http {
...
add_header Access-Control-Allow-Origin * always;
# add_header Access-Control-Allow-Origin 'http://www.demo.com';
...
}
前端
node
中间件代理,此方案只能开发环境使用,无法解决生产环境问题JSONP