跨域请求

同源

同源策略(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

 

posted @ 2019-07-08 16:50  yyfgrd  阅读(167)  评论(0)    收藏  举报