同源策略和跨域请求

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> 同源策略和跨域请求

点击上方”python宝典”,关注获取python全套视频,

技术文章第一时间送达!

跨域请求

同源策略机制

浏览器有一个很重要的概念——同源策略(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  //返回:scriptfun1("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宝典

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> 同源策略和跨域请求


 上一篇
Django工程的分层结构 Django工程的分层结构
前言传统上我们都知道在Django中的MTV模式,具体内容含义我们再来回顾一下: M:是Model的简称,它的目标就是通过定义模型来处理和数据库进行交互,有了这一层或者这种类型的对象,我们就可以通过对象来操作数据。 V:是View的简称,
2021-04-05
下一篇 
异常处理 异常处理
点击上方”python宝典”,关注获取python全套视频, 技术文章第一时间送达! 什么是异常异常就是程序运行时发生错误的信号(在程序出现错误时,则会产生一个异常,若程序没有处理它,则会抛出该异常,程序的运行也随之终止),在python中
2021-04-05