跨域请求
同源
同源策略(Same origin policy)是一种约定, 它是浏览器最核心也是最基本的安全功能, 如果缺少了同源策略, 则浏览器的正常功能都会受影响, 可以说web是构建在同源策略基础之上的, 浏览器只是针对同源策略的一种实现
跨域
请求的url地址必须与浏览器上的url地址处于同域上, 也就是域名、端口和协议都相同
比如: 我在本地上的域名是127.0.0.1:8000, 请求另外一个域名: 127.0.0.1:8001上的一段数据浏览器上就会报错, 这个就是同源策略的保护, 如果浏览器对javascript没有同源策略的保护, 那么一些重要的机密网站将会很危险
已拦截跨源请求:同源策略禁止读取位于 http://127.0.0.1:8001/SendAjax/ 的远程资源。(原因:CORS 头缺少 'Access-Control-Allow-Origin')。
例如http://www.example.com/
|
url |
同源/不同源 |
描述 |
|
http://api.example.com/detail.html |
不同源 |
域名不同 |
|
https//www.example.com/detail.html |
不同源 |
协议不同 |
|
http://www.example.com:8080/detail.html |
不同源 |
端口不同 |
|
http://api.example.com:8080/detail.html |
不同源 |
域名、端口不同 |
|
https://api.example.com/detail.html |
不同源 |
协议、域名不同 |
|
https://www.example.com:8080/detail.html |
不同源 |
端口、协议不同 |
|
http://www.example.com/detail/index.html |
同源 |
只是目录不同 |
CORS(跨域资源共享)简介
CORS需要浏览器和服务器同时支持, 目前所有浏览器的支持该功能, IE浏览器不能低于IE10
整个CORS通信过程,都是浏览器自动完成的, 不需要用户参与, 对于开发者来说, CORS通信与同源的AJAX通信没有差别, 代码完全一样, 浏览器一旦发现AJAX请求跨源, 就会自动添加一些附加的头信息, 又时还会多出一次附加的请求, 但用户不会有感觉
因此, 实现CORS通信的关键是服务器, 只要服务器实现了CORS接口, 就可以跨源通信
CORS基本流程
浏览器将CORS请求分成两类: 简单请求(simple request) 和非简单请求(not-so-simple request)
浏览器发出CORS简单请求, 只需要在头信息之中增加一个Origin字段
浏览器发出CORS非简单请求, 会在正式通信之前, 增加一次HTTP查询请求, 称为"预检"请求(preflight), 浏览器会先询问服务器, 当前网页所在的域名是否在服务器的许可名单之中, 以及可以使用哪些HTTP动词和头信息字段, 只有得到肯定答复, 浏览器才会发出正式的XMLHttpRequest请求, 否则就报错
CORS两种请求详解
只需要同时满足一下量大条件, 就属于简单请求
(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
凡是不同满足上面连个条件, 就是非简单请求
浏览器对着两种请求的处理, 是不一样的
简单请求: 一次请求,在发送数据之前会先发一次请求用于做'预检', 只有'预检'通过后才再发送一次请求用于数据传输 非简单请求: 两次请求, 再发送数据之前会先发一次请求用于做'预检', 只有'预检'通过后才在发送一次请求用于数据传输
关于'预检' 请求方式: OPTIONS '预检'其实做检查,检查如果通过则允许传输数据, 检查不通过则不再发送真正想要的发送的消息 如何'预检' 如果复杂请求是PUT请求, 则服务端需要设置允许某请求, 否则'预检'不通过 Access-Control-Request-Method 如果复杂请求设置了请求头, 则服务端需要设置允许某请求头, 否则'预检'不通过 Access-Control-Request-Headers

简单请求
服务器设置响应头: Access-Control-Allow-Origin = '域名'或'*'
def index(request): res = HttpResponse(123) # res['Access-Control-Allow-Origin'] = '*' res['Access-Control-Allow-Origin'] = 'http://127.0.0.1:8001' return res

复杂请求 由于复杂请求时, 首先发送'预检'请求, 如果'预检'成功, 则发送真实数据 '预检' 请求时, 允许请求方式则需服务器设置响应头: Access-Control-Request-Method '预检' 请求时, 允许请求头则需服务器设置响应头: Access-Control-Request-Headers def index(request): print(request.method) # OPTIONS res = HttpResponse(123) # res['Access-Control-Allow-Origin'] = '*' res['Access-Control-Allow-Origin'] = 'http://127.0.0.1:8001' # res['Access-Control-Allow-Headers'] = '*' res['Access-Control-Allow-Headers'] = 'Content-Type' return res

浙公网安备 33010602011771号