django之同源策略

什么是同源策略php

同源策略,它是由Netscape提出的一个著名的安全策略。如今全部支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。当一个浏览器的两个tab页中分别打开来 百度和谷歌的页面,当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪一个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。若是非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。html

简单来讲,端口不一样或者域名不一样,就会有庭院策略问题ajax

什么是JSONPjson

首先提一下JSON这个概念,JSON是一种轻量级的数据传输格式,被普遍应用于当前Web应用中。JSON格式数据的编码和解析基本在全部主流语言中都被实现,因此如今大部分先后端分离的架构都以JSON格式进行数据的传输。后端

那么JSONP是什么呢? 
首先抛出浏览器同源策略这个概念,为了保证用户访问的安全,现代浏览器使用了同源策略,即不容许访问非同源的页面,详细的概念你们能够自行百度。这里你们只要知道,在ajax中,不容许请求非同源的URL就能够了,好比www.a.com下的一个页面,其中的ajax请求是不容许访问www.b.com/c.php这样一个页面的。跨域

JSONP就是用来解决跨域请求问题的,那么具体是怎么实现的呢?浏览器

JSONP原理安全

ajax请求受同源策略影响,不容许进行跨域请求,而script标签src属性中的连接却能够访问跨域的js脚本,利用这个特性,服务端再也不返回JSON格式的数据,而是返回一段调用某个函数的js代码,在src中进行了调用,这样实现了跨域。服务器

JSONP的具体实现
架构

<!DOCTYPE html>
<html>
<head>
    <title>GoJSONP</title>
</head>
<body>
 $(".jsonp_test").click(function () {
    $.ajax({
        url:"http://127.0.0.1:8008/service/",
        type:"get",
        dataType:"jsonp",     // 伪造ajax  基于script
        jsonp: 'callbacks',    //至关于?callbacks=alex
        //jsonpCallback:"alex",
        success:function (data) {
            console.log(data)
        }
    })
})
<button class='jsop_test'>测试</button>
</body> </html>
127.0.0.1:8000中的index.html
import json
def jsonp_test(request):
    func=request.GET.get("callbacks") #获取请求的callbacks参数
    info={"name":"fuyong","age":18} #定义数据
    return HttpRespons
import json
def jsonp_test(request):
    func=request.GET.get("callbacks") #获取请求的callbacks参数
    info={"name":"fuyong","age":18} #定义数据
    return HttpResponse("%s ('%s')"%(func,json.dumps(info))) #传json对象
http://127.0.0.1:8008/service/的views

 JSONP总结

一句话就是利用script标签绕过同源策略,得到一个相似这样的数据。ajax里边的callbacks本质上是(假装成script标签src属性发送请求的方式)发送一个回调方法,参数data就是想获得的json数据。

CORS实现跨域请求

CORS:Cross-Origin Resource Sharing(CORS)跨来源资源共享是一份浏览器技术的规范,提供了 Web 服务从不一样域传来沙盒脚本的方法,以避开浏览器的同源策略,是 JSONP 模式的现代版。与 JSONP 不一样,CORS 除了 GET 要求方法之外也支持其余的 HTTP 要求。用 CORS 可让网页设计师用通常的 XMLHttpRequest,这种方式的错误处理比 JSONP 要来的好 。另外一方面,JSONP 能够在不支持 CORS 的老旧浏览器上运做。现代的浏览器都支持 CORS。

CORS对比JSONP

都能解决 Ajax直接请求普通文件存在跨域无权限访问的问题

  1. JSONP只能实现GET请求,而CORS支持全部类型的HTTP请求
  2. 使用CORS,开发者可使用普通的XMLHttpRequest发起请求和得到数据,比起JSONP有更好的错误处理
  3. JSONP主要被老的浏览器支持,它们每每不支持CORS,而绝大多数现代浏览器都已经支持了CORS

 CORS的实现思路

CORS背后的基本思想是使用自定义的HTTP头部容许浏览器和服务器相互了解对方,从而决定请求或响应成功与否。

例如 localhost:63343 经过Ajax请求http://192.168.10.61:8080服务器资源时就会出现异常,其实数据已经获取到了,可是因为同源策略的限制给禁止了,提示说header里没有Access-Control-Allow-Origin,那么,咱们在发送响应的时候的只须要给header里加上这个参数就好了。

 CORS的实现

CORS有不少种实现方式,这里介绍一种最简单最直观的的方式,就是修改views.py中对应函数,给它的响应头部添加Access-Control-Allow-Origin餐具容许其余域经过Ajax请求数据,以下:

def cors_test(request):
    info={"name":"egon","age":34,"price":200} #数据
    response=HttpResponse(json.dumps(info)) #序列化数据
    #response["Access-Control-Allow-Origin"]="http://127.0.0.1:8006" #指定ip可访问
    #response["Access-Control-Allow-Origin"]="*"#全部ip都可访问
    return  response #返回数据
views.py

下面的代码实现了经过添加中间件的方式实现跨域请求

class MiddlewareMixin(object):
    def __init__(self, get_response=None):
        self.get_response = get_response
        super(MiddlewareMixin, self).__init__()
 
    def __call__(self, request):
        response = None
        if hasattr(self, 'process_request'):
            response = self.process_request(request)
        if not response:
            response = self.get_response(request)
        if hasattr(self, 'process_response'):
            response = self.process_response(request, response)
        return response
 
class CORSMiddleware(MiddlewareMixin):
 
    def process_response(self,request,response):
        # 添加响应头
 
        # 容许你的域名来获取个人数据
        response['Access-Control-Allow-Origin'] = "*"
 
        # 容许你携带Content-Type请求头
        response['Access-Control-Allow-Headers'] = "Content-Type"
 
        # 容许你发送DELETE,PUT
        response['Access-Control-Allow-Methods'] = "DELETE,PUT"
 
        return response
cors.py
MIDDLEWARE = [
   .....
 
    'xxx.cors.CORSMiddleware',  # xxx为cors.py所在包的目录
]
settings
相关文章
相关标签/搜索