同源策略

首先基于安全的原因,浏览器是存在同源策略这个机制的,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性。

而如果我们要跳过这个策略,也就是说非要跨域请求,那么就需要通过JSONP或者CORS来实现了。

JSONP

什么是JSONP

首先提一下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具体实现

127.0.0.1:8000中的index.html

<!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',
//jsonpCallback:"alex",
success:function (data) {
console.log(data)
}
})
})
<button class='jsop_test'>测试</button>
</body> </html>

  

127.0.0.1:8080的views

import json
def jsonp_test(request):
func=request.GET.get("callbacks") #获取请求的callbacks参数
info={"name":"fuyong","age":18} #定义数据
return HttpResponse(" ('%s')"%(func,json.dumps(info))) #传json对象

总结

一句话就是利用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 #返回数据

  

实例

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

cors.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

  

settings.py

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

  

Django之跨域请求的更多相关文章

  1. django允许跨域请求配置

    django允许跨域请求配置 下载corsheader pip install django-cors-headers 修改setting.py中配置 在INSTALLED_APPS中增加corshe ...

  2. django解决跨域请求的问题

    跨域请求可以用jsonp来解决,不过今天我发现一个很好用的包:django-cors-headers 只需要简单地配置一下就可 被请求方的setting.py中的配置如下: INSTALLED_APP ...

  3. Django之跨域请求同源策略

    同源策略: 首先基于安全的原因,浏览器是存在同源策略这个机制的,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性. 而如果我们要跳过这个策略,也就是说非要跨域请求,那么就需要通过 ...

  4. Python django解决跨域请求的问题

    解决方案 1.安装django-cors-headers pip3 install django-cors-headers 2.配置settings.py文件 INSTALLED_APPS = [ . ...

  5. django - 总结 - 跨域请求

    script ->jsonp跨域 浏览器的同源策略:不能跨越网站请求信息: XMLHttpRequests遵循这个规定. 因此ajax等基于XML的都不能进行跨站请求 而我们知道img,ifra ...

  6. Django的跨域请求

    一 同源策略 同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响.可以说Web是构建在同源策略基础之 ...

  7. django 支持跨域请求配置

    参考:https://www.jianshu.com/p/63fb55bee142 核心注意点:

  8. Django跨域请求之JSONP和CORS

    现在来新建一个Django项目server01,url配置为 url(r'^getData.html$',views.get_data) 其对应的视图函数为get_data: from django. ...

  9. $Django 前后端之 跨域问题(同源策略) vue项目(axios跨域请求数据)

    1 跨域问题(多个域之间的数据访问) #同源策略(ip port 协议全部相同) #本站的只能请求本站域名的数据 #CORS实现(跨域资源共享) #实现CORS通信的关键是服务器.只要服务器实现了CO ...

随机推荐

  1. Python 键盘鼠标监听

    异想天开的想记录一下自己每天的键盘键位走向,于是就在网上搜索了一下相关的实现,然后就发现了一个第三方的库pyHook.封装的很好,我们只需要傻瓜式的调用里面的API就可以了. 下面是我在使用pyHoo ...

  2. Intent和PendingIntent的区别

    intent英文意思是意图,pending表示即将发生或来临的事情.  PendingIntent这个类用于处理即将发生的事情.比如在通知Notification中用于跳转页面,但不是马上跳转.  I ...

  3. Android实现登录小demo

    安卓,在小编实习之前的那段岁月里面,小编都没有玩儿过,如果说玩儿过,那就是安卓手机了,咳咳,敲登录的时候有种特别久违的熟悉,这种熟悉的感觉就和当时敲机房收费系统一样,那叫一个艰难啊,不过小编相信,在小 ...

  4. C++中友元详解

    问题的提出 我们已知道类具备封装和信息隐 藏的特性.只有类的成员函数才能访问类的私有成员,程式中的其他函数是无法访问私有成员的.非成员函数能够访问类中的公有成员,但是假如将数据成员都定义 为公有的,这 ...

  5. 精通CSS+DIV网页样式与布局--页面和浏览器元素

    在页面和浏览器中,除了文字.图片.表格.表单等,还有很多各种各样的元素,在上篇博文中,小编主要简单的介绍了一下在CSS中如何设置表格和表单,今天小编主要简单介绍一下丰富的超链接特效.鼠标特效.页面滚动 ...

  6. uploadify 3.2 java应用丢失session

    flash中有个bug就是自身创建一个session,这样就导致与web本身的session不一致 权限验证失败的问题.  原因: 因为uploadify是不会自动传送session值的,所以当ses ...

  7. Tomcat的管道

    Tomcat中按照包含关系一共有四个容器--StandardEngine.StandardHost.StandardContext和StandardWrapper,对这四个容器的详细解析后面会涉及,请 ...

  8. 安装Compass时不能访问服务器的问题

    今天安装Compass,居然老是提示网络问题,后来根据错误提示,发现带https的域名是访问不了的,是是SSL问题.后来搜了一下,在stackoverflow找到一个人说,将https的去掉就好了.具 ...

  9. OJ题:将一个字符串顺序翻转

    题目描述 写出一个程序,接受一个字符串,然后输出该字符串反转后的字符串. 之前写过这样的一个程序,用位运算的方法去操作指针,但是那样的方法未免就有点复杂啦,不如用以下这种,简单明了. 程序如下: #i ...

  10. (三十二)DatePicker和自定义键盘

    DatePicker通过设置Locale属性可以设置语言(注意手机语言也会影响到它的显示). 如果通过代码创建DatePicker,又要设置属性,使用下面的代码,注意locale是个枚举,初始化要填写 ...