时间:2021-05-22
因为浏览器的同源策略限制,不是同源的脚本不能操作其他源下面的资源,想操作另一个源下面的资源就属于跨域了,这里说的跨域是广义跨域,我们常说的代码中请求跨域,是狭义的跨域,即在脚本代码中向非同源域发送http请求
浏览器的同源策略(SOP/same origin policy)是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS(跨站脚本攻击 cross site scripting)和CSRF(跨站请求伪造cross-site request forgery)等攻击。
(同源 origin:协议,域名,端口号,不清楚的话,直接在浏览器控制台中输入window.location.origin看看返回值就知道了。)
下面两种情况,是不受跨域限制的,严格来讲,这两种情况只是跨站资源请求:
1)页面中的链接,重定向及表单提交是不受同源策略限制的
2)跨域资源的引入,如<script src=""> <image src=""> <iframe>等
从上面的第二种情况,我们可以发现,但凡通过src去获取非同源状态的资源时,都是不受跨域限制的,那我们就可以想想,是否可以借助这种跨站资源请求的方式来实现http跨域请求呢?这就是我们接下来要说的第一种跨域解决方案:jsonp
1、JSONP(不仅限于python,所有的GET请求都可以使用jsonp实现跨域)
1)实现原理:
从上面的分析我们已经知道,web页面上请求跨站资源请求是不会受到同源策略限制的,所有我们会想,我们可不可以在服务器上想办法把web端需要的数据装进一个js文件里面,然后让web端直接访问这个js文件,从而获取需要的数据呢?恰巧我们知道有一种叫做json的数据格式,且js原生支持,所以web端就可以通过像访问js脚本一样的方式,来调用跨域服务器上动态生成的js文件。
为了便于客户端使用数据,逐渐形成一种非正式传输协议:JSONP。JSONP的一个要点就是,传给服务器一个callback参数,然后服务器返回数据时,将这个callback参数作为函数名来包裹住json数据
2)jsonp实例
在远程服务器上新建一个remote.js文件:
HandleRemote({"title":"哈哈", "name":"我是一个测试数据哦!"})
在本地新建html文件:
function HandleRemote(data){console.log(data.title+data.name);}<script type="text/javascript" src="远程服务器地址/remote.js">运行本地文件,在浏览器的控制台可以看到 哈哈我是一个测试数据哦! 的输出
到现在我们已经实现了去服务器上获取数据,剩下还有两个问题需要我们思考:
a、我们如何让远程服务器知道他要调用的本地函数回调函数的名字是什么?
b、我们如何在远程服务器上动态生成js脚本
有了思路就很好办了,先看第一个问题:
我们如何让服务器知道我们本地的回调函数名?告诉他就行了啊,在请求中加上我们的函数名,然后让远程服务器根据我们的参数取动态生成js脚本调用函数名即可!
前端实现
var url = "http://test.com/getRemoteDate?callback=HandleRemote"var script = document.createElement("script");script.setAttribute("src", url)document.getElementByTagName("head")[0].appendChild(script);最后将上面的代码封装成通用的ajax形式:
url = "http://test.com/getRemoteDate/";$.ajax({url:url,type:"GET",dataType:"JSONP",jsonp:"callback", #将会作为参数传给服务器,用于获得回调函数的参数名jsonCallback:"test", # 自定义的jsonp的回调函数参数名,默认为jQuery自动生成的函数名,也可以自定义,jQuery会自动为你处理的。success:function(data){此处data即为返回的json数据了,前端根据需要自行处理} });服务端代码 :
def getData():return {"title":"哈哈", "name":"这又是一个测试数据哦!"}def getRemote(request):funcName = request.GET.get("callback")result = getData()# 将结果以json形式返回,与前端的jsonp交互return funcName+"("+json.dumps(result)+")"配置url:
url(r"^getRemoteData/$", getRemote)
到这里,jsonp就完成了,虽然jsonp不受同源策略的限制,但是jsonp有个问题,就是它只支持GET请求,其他请求不支持。
2、在响应头加上响应的允许跨域的参数,告诉浏览器当前请求被服务器接受,这种跨域方式也是通用的。
3、python Django中最常用的另一种处理跨域的方式:
使用Django提供的 Django-cors-headers 来处理跨域
从GitHub上面下载Django-cors-headers
pip install Django-cors-headers.zip
在settings.py中的中间件中配置 【'corsheaders.middleware.CorsMiddleware',】记得这个中间件一定要写在CSRF之前,为了方便处理,一般写在最前面
设置 CORS_ORIGIN_ALLOW_ALL = True,即允许所有的跨域请求,当然,这里也可以设置为False,然后配合 CORS_ORIGIN_WHITELIST 白名单来使用
如此,我们的跨域处理即完成,支持所有的请求。
补充知识:python WSGI 解决跨域问题
import jsonfrom wsgiref.simple_server import make_server# application()函数是Python中符合WSGI标准的一个HTTP处理函数,返回是一个字符串def application(environ, start_response): # start_response 如下调用就会发送HTTP响应的Header,注意只能调用一次start_response()函数发送Header。 # start_response 函数两个参数,一是HTTP响应码,一是一组list表示的HTTP Header,每个Header用一个包含两个str的数组表示 status = '200 OK' # response_headers 中添加请求头部 ,解决跨域问题 response_headers = [('Content-type', 'application/json'), ('Access-Control-Allow-Origin', '*'), ('Access-Control-Allow-Methods', 'POST'), ('Access-Control-Allow-Headers', 'x-requested-with,content-type'), ] # json start_response(status, response_headers) result = {'code': 200, 'message': "You get the flag"} return [result.encode()] if __name__ == "__main__": port = 8091 httpd = make_server("127.0.0.1", port, application) print("serving http on port {0}...".format(str(port))) httpd.serve_forever()以上这篇关于python 跨域处理方式详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
本文实例讲述了jQuery实现ajax调用WCF服务的方法。分享给大家供大家参考,具体如下:关于AJAX调用WCF服务分为跨域和不跨域两种方式,今天咱们先介绍下
前言以前在面试的时候经常遇到问关于跨域的事儿,所以自己对跨域有一定的概念性了解,知道什么是跨域以及解决跨域的方法,但是具体实际从来没有操作过,直到最近在公司项目
安装Pycharm进行Python开发时,经常右下角提示NoRinterpreterdefined,处理方式:1、安装R,然后将R的路径添加到Pycharm中:
PHPSSO详解SSO有三种模式:①跨子域单点登陆②完全跨单点域登陆③站群共享身份认证第一种模式很简单,只需要将Cookie的域设置成多个应用的根域即可第二种方
由于JS同源策略的影响,因此js只能访问同域名下的文档。因此要实现跨域,一般有以下几个方法:一、处理跨域的方式:1.代理2.XHR2HTML5中提供的XMLHT