同源策略,它是由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>

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对象
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直接请求普通文件存在跨域无权限访问的问题
- JSONP只能实现GET请求,而CORS支持全部类型的HTTP请求
- 使用CORS,开发者可使用普通的XMLHttpRequest发起请求和得到数据,比起JSONP有更好的错误处理
- 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 #返回数据
下面的代码实现了经过添加中间件的方式实现跨域请求

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

MIDDLEWARE = [ ..... 'xxx.cors.CORSMiddleware', # xxx为cors.py所在包的目录 ]