返回顶部

【JavaScript】--重点解析之跨域请求

JSON

  JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。

  JSON是用字符串来表示Javascript对象,例如可以在django中发送一个JSON格式的字符串给客户端Javascript,Javascript可以执行这个字符串,得到一个Javascript对象。

  json就是js对象的一种表现形式(字符串的形式)

JSON对象语法

  json语法:

  • 数据在名称/值对中
  • 数据由逗号分隔
  • 花括号保存对象(对象需要使用大括号起来)
  • 方括号保存数组(数组使用中括号括起来)
var person = {"name":"zhangSan", "age":"18", "sex":"male"};
alert(person.name + ", " + person.age + ", " + person.sex);

 

注意,key也要在双引号中!

JSON值:

  • 数字  (整数或浮点数)
  • 字符串(在双引号中)
  • 逻辑值(true 或 false)
  • 数组   (在方括号中)
  • 对象   (在花括号中)
  • null
var person = {"name":"alex", "age":"18", "sex":"male", "hobby":["girl", "movie", "travle"]};
alert(person.name + ", " + person.age + ", " + person.sex + ", " + person.hobby);

 

带有方法的JSON对象:

var person = {"name":"alex",
              "sex":"men",
              "teacher":{
                 "name":"tiechui",
                  "sex":"half_men",
              },
              "bobby":['basketball','running'],

               "getName":function() {return 80;}
              };
alert(person.name);
alert(person.getName());
alert(person.teacher.name);
alert(person.bobby[0]);

 

js接受python的json对象:

在json的编码过程中,会存在从python原始类型向json类型的转换过程,具体的转换
    如下:

        python         -->        json
        dict                      object
        list,tuple                array
        str,unicode               string
        int,long,float            number
        True                      true
        False                     false
        None                      null

 

js与django的交互

def login(request):
    obj={'name':"alex111"}
    return render(request,'index.html',{"objs":json.dumps(obj)})
#----------------------------------
 <script>
     var temp={{ objs|safe }}
     alert(temp.name);
     alert(temp['name'])
 </script>

 

 

JSON与XML比较

  • 可读性:   XML胜出;
  • 解码难度:JSON本身就是JS对象(主场作战),所以简单很多;
  • 流行度:   XML已经流行好多年,但在AJAX领域,JSON更受欢迎。

parse()和.stringify()

parse用于从一个字符串中解析出json对象,如

var str = '{"name":"yuan","age":"23"}'

结果:

JSON.parse(str)

Object

age: "23"
name: "yuan"


注意:单引号写在{}外,每个属性名都必须用双引号,否则会抛出异常。


stringify()用于从一个对象解析出字符串,如

var
 a = {a:1,b:2}

结果:

JSON.stringify(a)

"{"a":1,"b":2}"

 

 跨域请求

  同源策略机制

  浏览器有一个很重要的概念——同源策略(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这里我们理解为填充)

#---------------------------http://127.0.0.1:8001/login

 def login(request):
    print('hello ajax')
    return render(request,'index.html')
 #---------------------------返回用户的index.html
 <h1>发送JSONP数据</h1>


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

#-----------------------------http://127.0.0.1:8002/get_byjsonp

def get_byjsonp(req):
    print('8002...')
    return HttpResponse('fun1("苑昊")')

 

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

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

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

<script>
    function addScriptTag(src){
     var script = document.createElement('script');
         script.setAttribute("type","text/javascript");
         script.src = src;
         document.body.appendChild(script);
    }
    function fun1(arg){
        alert("hello"+arg)
    }

    window.onload=function(){
        addScriptTag("http://127.0.0.1:8002/get_byjsonp/")
    }
</script>

 

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

<script>
    function addScriptTag(src){
     var script = document.createElement('script');
         script.setAttribute("type","text/javascript");
         script.src = src;
         document.body.appendChild(script);
    }
    function fetch(arg){
        alert("hello"+arg)
    }

    window.onload=function(){
        addScriptTag("http://127.0.0.1:8002/get_byjsonp?callback=fetch")
    }
    
</script>

#--------------------------------http://127.0.0.1:8002/get_byjsonp    
    def get_byjsonp(req):

    callback=req.GET.get('callback')
    print(callback)
    return HttpResponse('%s("yuan")'%callback)
View Code

 

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:"fetch"
   });
    function fetch(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)
View Code

 

another way:

<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',
        success:function(data){
            alert(data)
        }
   });

</script>
 #-------------------------------------http://127.0.0.1:8002/get_byjsonp
def get_byjsonp(req):

    callback=req.GET.get('callbacks')
    print(callback) #jQuery223015502220591490135_1477560648881
return HttpResponse("%s('yuan')"%callback)
View Code

 

  没错,jsonpCallback就是可以指定我们自己的回调方法名fetch,远程服务接受callback参数的值就不再是自动生成的回调名,而是fetch。dataType是指定按照JSOPN方式访问远程服务。callback必须有,因为服务端根据它来去回调函数的名字,如果是自已定义的,那么就得有自定义的名字:jsonpCallback:"fetch";如果不加这个参数,则自动生成一个随机名字。

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

 

posted @ 2016-12-01 16:40  Will_D_Zhang  阅读(367)  评论(0编辑  收藏  举报