同源策略和跨域请求

跨域请求

同源策略机制

浏览器有一个很重要的概念——同源策略(Same-Origin Policy)。所谓同源是指,域名,协议,端口相同。不同源的客户端脚本(javascript、ActionScript)在没明确授权的情况下,不能读写对方的资源。

简单的来说,浏览器允许包含在页面A的脚本访问第二个页面B的数据资源,这一切是建立在A和B页面是同源的基础上。

如果Web世界没有同源策略,当你登录淘宝账号并打开另一个站点时,这个站点上的JavaScript可以跨域读取你的淘宝账号数据,这样整个Web世界就无隐私可言了。

 

jsonp的js实现

JSONP是JSON with Padding的略称。可以让网页从别的域名(网站)那获取资料,即跨域读取数据。

它是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。

JSONP就像是JSON+Padding一样(Padding这里我们理解为填充)

实例:

<script>
   function fun1(arg){
       alert("hello"+arg)
   }
</script>
<script src="http://127.0.0.1:8002/get_byjsonp/"></script>  //返回:<script>fun1("yuan")</script>

#-----------------------------http://127.0.0.1:8002/get_byjsonp
def get_byjsonp(req):
   print('8002...')
   return HttpResponse('fun1("yuan")')

这其实就是JSONP的简单实现模式,或者说是JSONP的原型:创建一个回调函数,然后在远程服务上调用这个函数并且将JSON 数据形式作为参数传递,完成回调。

将JSON数据填充进回调函数,这应该就是JSONP的JSON+Padding的含义吧。

      一般情况下,我们希望这个script标签能够动态的调用,而不是像上面因为固定在html里面所以没等页面显示就执行了,很不灵活。我们可以通过javascript动态的创建script标签,这样我们就可以灵活调用远程服务了。

<button onclick="f()">submit</button>
<script>
   function addScriptTag(src){
    var script = document.createElement('script');
        script.setAttribute("type","text/javascript");
        script.src = src;
        document.body.appendChild(script);
        document.body.removeChild(script);
   }
   function fun1(arg){
       alert("hello"+arg)
   }
   function f(){
        addScriptTag("http://127.0.0.1:8002/get_byjsonp/")
   }
</script>

为了更加灵活,现在将你自己在客户端定义的回调函数的函数名传送给服务端,服务端则会返回以你定义的回调函数名的方法,将获取的json数据传入这个方法完成回调:

<button onclick="f()">submit</button>
<script>
   function addScriptTag(src){
    var script = document.createElement('script');
        script.setAttribute("type","text/javascript");
        script.src = src;
        document.body.appendChild(script);
        document.body.removeChild(script);
   }
   function SayHi(arg){
       alert("Hello "+arg)
   }
   function f(){
        addScriptTag("http://127.0.0.1:8002/get_byjsonp/?callbacks=SayHi")
   }
</script>
----------------------views.py
def get_byjsonp(req):
   func=req.GET.get("callbacks")
   return HttpResponse("%s('yuan')"%func)

jQuery对JSONP的实现

jQuery框架也当然支持JSONP,可以使用$.getJSON(url,[data],[callback])方法

<script type="text/javascript">
   $.getJSON("http://127.0.0.1:8002/get_byjsonp?callback=?",function(arg){
       alert("hello"+arg)
   });
</script>

结果是一样的,要注意的是在url的后面必须添加一个callback参数,这样getJSON方法才会知道是用JSONP方式去访问服务,callback后面的那个问号是内部自动生成的一个回调函数名。

      此外,如果说我们想指定自己的回调函数名,或者说服务上规定了固定回调函数名该怎么办呢?我们可以使用$.ajax方法来实现

<script type="text/javascript" src="/static/jquery-2.2.3.js"></script>
<script type="text/javascript">
  $.ajax({
       url:"http://127.0.0.1:8002/get_byjsonp",
       dataType:"jsonp",
       jsonp'callbacks',
       jsonpCallback:"SayHi"
  });
   function SayHi(arg){
       alert(arg);
   }
</script>

#--------------------------------- http://127.0.0.1:8002/get_byjsonp
def get_byjsonp(req):
   callback=req.GET.get('callbacks')
   print(callback)
   return HttpResponse('%s("yuan")'%callback)

当然,最简单的形式还是通过回调函数来处理:

<script type="text/javascript" src="/static/jquery-2.2.3.js"></script>
<script type="text/javascript">
  $.ajax({
       url:"http://127.0.0.1:8002/get_byjsonp",
       dataType:"jsonp",            //必须有,告诉server,这次访问要的是一个jsonp的结果。
       jsonp: 'callbacks',          //jQuery帮助随机生成的:callbacks="wner"
       success:function(data){
           alert(data)
       }
  });
</script>
#-------------------------------------http://127.0.0.1:8002/get_byjsonp
def get_byjsonp(req):

   callbacks=req.GET.get('callbacks')
   print(callbacks)                 #wner  

return HttpResponse("%s('yuan')"%callbacks)

 jsonp: 'callbacks'就是定义一个存放回调函数的键,jsonpCallback是前端定义好的回调函数方法名'SayHi',server端接受callback键对应值后就可以在其中填充数据打包返回了; 

       jsonpCallback参数可以不定义,jquery会自动定义一个随机名发过去,那前端就得用回调函数来处理对应数据了。

     利用jQuery可以很方便的实现JSONP来进行跨域访问。  

注意1: JSONP一定是GET请求

注意2:

<button onclick="f()">submit</button>
<script src="/static/jquery-1.8.2.min.js"></script>
<script type="text/javascript">
   function f(){
       $.ajax({
       url:"http://127.0.0.1:8002/get_byjsonp",
       dataType:"jsonp",
       jsonp'callbacks',
       success :function(data){        //传过来的数据会被转换成js对象
           console.log(data);          //Object {name: Array[2]}
           console.log(typeof data);   //object
           console.log(data.name)      //["alex", "alvin"]
       }
  });
   }
</script>
---------------------------------------------views.py
def get_byjsonp(req):
   func=req.GET.get("callbacks")
   a=json.dumps({'name':('zhangsan','lisi')})
   return HttpResponse("%s(%s)"%(func,a))
   #return HttpResponse("%s({'name':('alex','alvin')})"%func)
   #return HttpResponse("%s('hello')"%func)
   #return HttpResponse("%s([12,34])"%func)
   #return HttpResponse("%s(5)"%func)

识别图中二维码,领取python全套视频资料

猜你喜欢

转载自www.cnblogs.com/IT-Scavenger/p/9261708.html
今日推荐