标签:移除 刷新 cdn cep 利用 pdo OLE tar 定向
如果两个页面的协议,端口(如果有指定)和域名都相同,则两个页面具有相同的源。
举个例子:
下表给出了相对http://a.xyz.com/dir/page.html同源检测的示例: URL 结果 原因 http://a.xyz.com/dir2/other.html 成功 协议,端口(如果有指定)和域名都相同 http://a.xyz.com/dir/inner/another.html 成功 协议,端口(如果有指定)和域名都相同 https://a.xyz.com/secure.html 失败 不同协议 ( https和http ) http://a.xyz.com:81/dir/etc.html 失败 不同端口 ( 81和80) http://a.opq.com/dir/other.html 失败 不同域名 ( xyz和opq)
同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。所以xyz.com下的js脚本采用ajax读取abc.com里面的文件数据是会被拒绝的。
同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。
页面中的链接,重定向以及表单提交是不会受到同源策略限制的。
跨域资源的引入是可以的。但是js不能读写加载的内容。如嵌入到页面中的<script src="..."></script>,<img>,<link>,<iframe>等。
下面来分步举例详细阐述其中的奥妙:
项目1(http://127.0.0.1:8000/)
项目2(http://127.0.0.1:8100/)
项目1
url: url(r‘index1/$‘,views.index1) views: def index1(request): return HttpResponse(‘wangjifei‘)
项目2
url: url(r‘index2/$‘,views.index2) views : def index2(request): return render(request,‘index2.html‘) index2.html: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>同源策略</title> </head> <body> <button id="btn">提交</button> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"> </script> <script> $(‘#btn‘).click(function () { $.ajax({ url:"http://127.0.0.1:8000/index1/", type:‘get‘, success:function (res) { console.log(res) } }) }) </script> </body> </html>
现在,打开使用浏览器打开 http://127.0.0.1:8100/index2/,点击页面上的 ‘提交‘ 按钮,会在console页面发现错误信息如下:
为什么报错呢?因为同源策略限制跨域发送ajax请求。
细心点的同学应该会发现我们的demo1项目其实已经接收到了请求并返回了响应,是浏览器对非同源请求返回的结果做了拦截。
再细心点的同学会发现,我们使用cdn方式引用的jQuery文件也是跨域的,它就可以使用。
同样是从其他的站点拿东西,script标签就可以。那我们能不能利用这一点搞点事情呢?
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>同源策略</title> </head> <body> <button id="btn">提交</button> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"> </script> <script src="http://127.0.0.1:8000/index1/"></script> </body> </html>
现在刷新一下会出现如下错误:
看来后端返回的响应已经被拿到了,只不过把wangjifei当成了一个变量来使用,但是该页面上却没有定义一个名为wangjifei的变量。所以出错了。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>同源策略</title> </head> <body> <button id="btn">提交</button> <script> var wangjifei = 123 </script> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"> </script> <script src="http://127.0.0.1:8000/index1/"></script> </body> </html>
刷新发现不报错了,
index2.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>同源策略</title> </head> <body> <button id="btn">提交</button> <script> function wangjifei() { console.log(‘出手就要专业‘) } </script> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"> </script> <script src="http://127.0.0.1:8000/index1/"></script> </body> </html>
项目1中的views:也修改一下
def index1(request): return HttpResponse(‘wangjifei()‘)
刷新一下页面显示结果:
结果分析:返回的 wangjifei(),页面上拿到这个响应之后直接执行了wangjifei函数!
index2.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>同源策略</title> </head> <body> <button id="btn">提交</button> <script> function wangjifei(res) { console.log(res) } </script> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"> </script> <script src="http://127.0.0.1:8000/index1/"></script> </body> </html>
项目1中的 views
from django.http import HttpResponse import json def index1(request): ret={‘code‘:1,‘msg‘:[110,119,120,12306]} res = json.dumps(ret) return HttpResponse(f‘wangjifei({res})‘)
刷新之后显示结果:
果然传递参数也是可以的!我们通过script标签的跨域特性来绕过同源策略拿到想要的数据了!!!
这其实就是JSONP的简单实现模式,或者说是JSONP的原型:创建一个回调函数,然后在远程服务上调用这个函数并且将JSON 数据形式作为参数传递,完成回调。
将JSON数据填充进回调函数,这就是JSONP的JSON+Padding的含义。
但是我们更多时候是希望通过事件触发数据的获取,而不是像上面一样页面一刷新就执行了,这样很不灵活。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>同源策略</title> </head> <body> <button id="btn">提交</button> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"> </script> <script> //自定义的函数 function wangjifei(res) { console.log(res) } //jquery给button绑定点击事件 $(‘#btn‘).click(function () { //创建一个script标签 var scriptEle = document.createElement(‘script‘); //给标签添加src属性,并添加对应的属性值 http://127.0.0.1:8000/index1 $(scriptEle).attr(‘src‘,‘http://127.0.0.1:8000/index1‘); //将创建好的标签添加到页面中,标签添加后就会自动触发get请求 $(‘body‘).append(scriptEle); //将标签移除 $(scriptEle).remove() }) </script> </body> </html>
这样当我们点击button按钮的时候,会在页面上插入一个script标签,然后从后端获取数据后再删除掉。
index2.html代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>同源策略</title> </head> <body> <button id="btn">提交</button> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"> </script> <script> //自定义的函数 function xxx(res) { console.log(res) } //jquery给button绑定点击事件 $(‘#btn‘).click(function () { //创建一个script标签 var scriptEle = document.createElement(‘script‘); //给标签添加src属性,并添加对应的属性值 http://127.0.0.1:8000/index1?callback=xxx $(scriptEle).attr(‘src‘,‘http://127.0.0.1:8000/index1?callback=xxx‘); //将创建好的标签添加到页面中,标签添加后就会自动触发get请求 $(‘body‘).append(scriptEle); //将标签移除 $(scriptEle).remove() }) </script> </body> </html>
项目1中views:
from django.http import HttpResponse import json def index1(request): ret={‘code‘:1,‘msg‘:[110,119,120,12306]} res = json.dumps(ret) callback = request.GET.get(‘callback‘) return HttpResponse(f‘{callback}({res})‘)
index2.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>同源策略</title> </head> <body> <button id="btn">提交</button> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"> </script> <script> //jquery给button绑定点击事件 $(‘#btn‘).click(function () { $.getJSON("http://127.0.0.1:8000/index1?callback=?",function (res) { console.log(res) }) }) </script> </body> </html>
要注意的是在url的后面必须要有一个callback参数,这样getJSON方法才会知道是用JSONP方式去访问服务,callback后面的那个?是jQuery内部自动生成的一个回调函数名。
index2.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>同源策略</title> </head> <body> <button id="btn">提交</button> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"> </script> <script> //jquery给button绑定点击事件 $(‘#btn‘).click(function () { $.ajax({ //要访问的url url:"http://127.0.0.1:8000/index1/", //要处理的数据类型jsonp dataType:‘jsonp‘, //自定义回调函数名必要参数 jsonp:‘callback‘, //自定义回调函数名,url中callback=后面的函数名 jsonpcallback:‘wangjifei‘ }) }); //回调函数 function wangjifei(res) { console.log(res) } </script> </body> </html>
views:
from django.http import HttpResponse import json def index1(request): ret={‘code‘:1,‘msg‘:[110,119,120,12306]} res = json.dumps(ret) callback = request.GET.get(‘callback‘) return HttpResponse(f‘wangjifei({res})‘)
index2.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>同源策略</title> </head> <body> <button id="btn">提交</button> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"> </script> <script> //jquery给button绑定点击事件 $(‘#btn‘).click(function () { $.ajax({ //要访问的url url:"http://127.0.0.1:8000/index1/", //要处理的数据类型jsonp dataType:‘jsonp‘, //success回调 success:function (res) { console.log(res) } }) }); //回调函数 function wangjifei(res) { console.log(res) } </script> </body> </html>
最后来一个jsonp的实际应用:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>同源策略</title> </head> <body> <button id="show-tv">提交</button> <div class="tv-list"></div> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script> <script> $("#show-tv").click(function () { $.ajax({ url: "http://www.jxntv.cn/data/jmd-jxtv2.html? callback=list&_=1454376870403", dataType: ‘jsonp‘, jsonp: ‘callback‘, jsonpCallback: ‘list‘, success: function (data) { var weekList = data.data; console.log(weekList); var $tvListEle = $(".tv-list"); $.each(weekList, function (k, v) { var s1 = "<p>" + v.week + "列表</p>"; $tvListEle.append(s1); $.each(v.list, function (k2, v2) { var s2 = "<p><a href=‘" + v2.link + "‘>" + v2.name + "</a></p>"; $tvListEle.append(s2) }); $tvListEle.append("<hr>"); }) } }) }); </script> </body> </html>
我们介绍了jsonp解决跨域请求问题,这种解决方式很好的诠释了跨域请求的本质,但是略显麻烦,是否还记得在我们不做任何处理的时候,跨域请求时候浏览器给我们报的错误不?翻译过来就是因为响应头没有指定Access-Control-Allow-Origin所允许原始的请求路径,因此原始请求路径http://127.0.0.1:8001不被允许访问。 基于上述的原因解释,我们只需要在响应的内容加入上述这样的授权字段,便可解决。
简单请求的定义:
只要同时满足以下两大条件,就属于简单请求,不满足就是复杂请求!!!
1.(1) 请求方法是以下三种方法之一:-- HEAD,GET,POST
2.(2)HTTP的头信息不超出以下几种字段:-- Accept
-- Accept-Language
-- Content-Language
-- Last-Event-ID
-- Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
由于django的所有请求响应都要走中间件,所以可以写一个跨域的中间件来解决跨域问题
from django.utils.deprecation import MiddlewareMixin class MyCore(MiddlewareMixin): def process_response(self, request, response): response[‘Access-Control-Allow-Origin‘] = "*" //简单请求 if request.method == "OPTIONS": # 复杂请求 预检 response[‘Access-Control-Allow-Headers‘] = "Content-Type" response[‘Access-Control-Allow-Methods‘] = "POST, DELETE, PUT" return response
标签:移除 刷新 cdn cep 利用 pdo OLE tar 定向
原文地址:https://www.cnblogs.com/sanxiao/p/11604442.html