CORS跨域
1、为什么发送预检请求
- 将不满足同源策略时,即协议、域名、端口 任意一个不同时,就是跨域请求。跨域+非简单请求时就会发送一个预检请求,即OPTIONS请求,来看服务端是否允许跨域请求。如果服务端的OPTIONS请求响应头中有:
Access-Control-Allow-Origin: http://localhost:8001
如果http://localhost:8001(前端地址)或 “ * ” ,那就是允许跨域的,那预检请求就是200 ok状态,然后再发送真实的请求。
- 如果是跨域+简单请求,响应中如果没有服务端设置的可跨域访问的头,浏览器拦截服务端响应的数据。
2、何为简单请求
那什么才是简单请求呢?需要满足如下两个条件:
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
3、总结
同源下:
不跨域,无CORS问题,没有预检请求。
跨域下:
简单请求:满足上面那两个条件时,可以访问,但响应中如果没有服务端设置的可跨域访问的头,但会被浏览器拦截。
非简单请求:需要发送预检请求(OPTIONS),预检请求通过发送真实请求。
4、实验:是否真的不跨域就不用发预检请求
实验文件:cors-nodejs-test.zip
预置环境:nodejs
启动:node ./server.js
简单分析代码:在server.js中写了一个后端API,是一个put请求(非简单请求),在static/index.html利用ajax发起请求后端put 这个请求。
访问1:http://localhost:5200/index.html #同源下,看控制台,无预检请求
访问2:使用vscode 的live server插件在 static/index.html 开一个服务器,访问:http://127.0.0.1:5500/static/index.html #跨域下,查看控制台,改送了一个预检请求且失败,因为后端不设置头,即不可跨域。
5、怎么解决跨域
1、后端在头中加可跨域
2、nginx,让前后端在同一源下
3、前端 jsonp 只能解决get请求