django中同源策略和跨域解决方案

一  同源策略

1.1何谓同源?

  • 若是两个页面的协议,端口(若是有指定)和域名都相同,则两个页面具备相同的
  • 举个例子:
  • 下表给出了相对http://a.xyz.com/dir/page.html同源检测的示例: 

1.2什么是同源策略?

  • 同源策略是浏览器的一个安全功能,不一样源的客户端脚本在没有明确受权的状况下,不能读写对方资源。因此xyz.com下的js脚本采用ajax读取abc.com里面的文件数据是会被拒绝的。
  • 同源策略限制了从同一个源加载的文档或脚本如何与来自另外一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。

1.3不受同源策略限制的?

  1. 页面中的连接,重定向以及表单提交是不会受到同源策略限制的。
  2. 跨域资源的引入是能够的。可是js不能读写加载的内容。如嵌入到页面中的<script src="..."></script>,<img>,<link>,<iframe>等。

二  CROS(跨域资源共享)

CORS须要浏览器和服务器同时支持。目前,全部浏览器都支持该功能,IE浏览器不能低于IE10。html

整个CORS通讯过程,都是浏览器自动完成,不须要用户参与。对于开发者来讲,CORS通讯与同源的AJAX通讯没有差异,代码彻底同样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感受。ajax

所以,实现CORS通讯的关键是服务器。只要服务器实现了CORS接口,就能够跨源通讯。django

三  CORS基本流程

3.1浏览器将CORS请求分红两类:

  • 简单请求(simple request)
  • 非简单请求(not-so-simple request
浏览器发出CORS:简单请求.只须要在头信息之中增长一个Origin字段。
浏览器发出CORS:非简单请求.会在正式通讯以前,增长一次HTTP查询请求,称为"预检"请求(preflight)。浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可使用哪些HTTP动词和头信息字段。只有获得确定答复,浏览器才会发出正式的XMLHttpRequest请求,不然就报错。

四  CORS两种请求详解

4.1只要同时知足如下两大条件,就属于简单的请求:

 

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

凡是不一样时知足上面两个条件,就属于非简单请求。json

浏览器对这两种请求的处理,是不同的。跨域

4.2简单请求和非简单请求的区别?

简单请求:一次请求
非简单请求:两次请求,在发送数据以前会先发一次请求用于作“预检”,只有“预检”经过后才再发送一次请求用于数据传输。
- 请求方式:OPTIONS
- “预检”其实作检查,检查若是经过则容许传输数据,检查不经过则再也不发送真正想要发送的消息
- 如何“预检”
     => 若是复杂请求是PUT等请求,则服务端须要设置容许某请求,不然“预检”不经过
        Access-Control-Request-Method
     => 若是复杂请求设置了请求头,则服务端须要设置容许某请求头,不然“预检”不经过
        Access-Control-Request-Headers
支持跨域,简单请求:
服务器设置响应头:Access-Control-Allow-Origin = '域名' 或 '*'
支持跨域复杂请求:
因为复杂请求时,首先会发送“预检”请求,若是“预检”成功,则发送真实数据。
“预检”请求时,容许请求方式则需服务器设置响应头:Access-Control-Request-Method
“预检”请求时,容许请求头则需服务器设置响应头:Access-Control-Request-Headers

五  Django项目中的应用

在返回结果中加入容许信息(简单请求):

def test(request):
    import json
    obj=HttpResponse(json.dumps({'name':'lqz'}))
    # obj['Access-Control-Allow-Origin']='*'
    obj['Access-Control-Allow-Origin']='http://127.0.0.1:8004'
    return obj

放到中间件中处理复杂和简单请求:

 
 
from django.utils.deprecation import MiddlewareMixin
class MyCorsMiddle(MiddlewareMixin):
    def process_response(self, request, response):
        # 简单请求:
        # 容许http://127.0.0.1:8001域向我发请求
        # ret['Access-Control-Allow-Origin']='http://127.0.0.1:8001'
        # 容许全部人向我发请求
        response['Access-Control-Allow-Origin'] = '*'
        if request.method == 'OPTIONS':
            # 全部的头信息都容许
            response['Access-Control-Allow-Headers'] = '*'
        return response

在settings中配置便可,在中间件中的位置能够随意放置.浏览器

相关文章
相关标签/搜索