JavaScript的jsonp

目录索引:

一、AJAX的概念
二、POST && GET
三、原生实现AJAX简单示例

  3.1 实现代码
  3.2 重点说明
四、框架隐藏域

  4.1 基本概念
  4.2 后台写入脚本
  4.3 JS主动判断Iframe的改变
  4.4 表单提交数据实战
五、JQ 的 AJAX
  5.1 load()
  5.2 $.get()
  5.3 $.post()
  5.4 $.getScript()
  5.5 $.getJson()
  5.6 $.ajax()
    a. 常用的属性说明
    b. 常用的事件说明
    c. 全局事件说明
    d. $.ajaxSetup()
  5.7 AJAX的再次封装
  5.8 序列化表单
六、JSONP的概念
  6.1 JSONP的概念
  6.2 自己封装的JSONP
  6.3 JQ的JSONP使用。

一、AJAX的概念

AJAX(Asynchronous JavaScript And XML) 中文翻译即“异步的JavaScript 和 XML”。
AJAX实际上是对现有的多种技术进行整合使用得到的技术。它包括:
  1) XMLHttpRequset:浏览器的XMLHttpRequset对象,该对象用于向后台发送请求与接收响应。
  2) JavaScript : 用于接收、处理、显示XMLHttpRequest响应后的内容。
  3) XML : (Extensible Mrakup Language) 扩展的标记语言,它规定了一种统一的,可跨平台与系统的文本标记格式,而在AJAX中则用于前端与后台的数据格式定义,但实际上,现在已经很少会有人使用这种格式进行数据的传输,更多的是采用JSON数据格                   式,相比之下前者用于说明数据结构的冗余代码更多,但是是结构清晰。
前面说过AJAX不是一种新的技术,而是对已有的技术进行整合得到的,其实AJAX的核心技术XMLHttpRequest是微软率先在IE5.0浏览器上实现的,只是那时候一值将该功能作为一个ActiveXObject的插件使用,在IE实现该功能后,其它的浏览器,如google、firefox等则以自己的方式也实现了该功能,但是这个功能并没有受到使用者的重视,一直到2005年谷歌在其旗下的Google Map和 Google Gmail等产品率先使用该技术,才让AJAX技术真正的流行开来。
AJAX将的基本功能就是,当用户在前端页面发起请求后,这个请求会被XMLHttpRequest对象发送到后台,后台接收请求后进行处理,并将结果按照规定的数据格式,重新发送到前端,当前端页面接响应收到的结果数据后,则会使用JS对数据进行解析、处理、展示等。


总之,AJAX技术的本质就是:实现页面无刷新数据动态更改。
相比之前需要通过刷新页面或者跳转链接才能获得响应的数据,AJAX具有以下几点优势:
  + 无刷新的数据获取,提高用户的体验性。
  + 减轻服务器的带宽
  + 后台与前端的紧密耦合
但是以上的优点,也会产生使用AJAX技术的缺点
  + 破坏浏览器的“前进”,“后退”按钮
  + 对搜索引擎的SEO支持不好。

二、POST && GET

POST 与 GET都是HTTP请求方式中的一种。而请求方式又决定了参数传输以及获取数据方式的不同。
这里,我们只需要知道与了解POST 与 GET在应用层方面的差异即可。
  ·  GET请求会将参数跟在URL后进行传递,而POST请求则是作为HTTP消息的实体内容发送给WEB服务器。
  ·  GET方式传输数据有大小限制(通常不能大于2KB),而POST上传输数据,理论上不受限制。
  ·  GET方式传输的数据会被浏览器缓存,因此使用GET方式传输账号,密码之类的,就会有很大的风险。
  ·  GET方式和POST方式传递的数据在服务器端的获取也不相同。在PHP中,GET方式的数据可以采用$_GET[]获取,而POST则是$_POST[]获取,但两种都可以使用$_REQUEST[]获取。

三、原生实现AJAX简单示例

 3.1 实现代码

  ·  前端代码 ·

 1 function ajaxGetData(params){
 2
 3     var xhr = null, //创建接受XMLHttpRequest对象变量
 4         method = params.method && params.method.toUpperCase() || ‘POST‘,
 5         url = params.url || ‘‘,
 6         data = params.data || null,
 7         async = params.async || true, //异步还是同步,默认异步。
 8         callback = params.callback || function(){};
 9
10
11     if(window.XMLHttpRequest){    //解决XMLHttpRequest对象的兼容性
12         xhr = new XMLHttpRequest();
13     }else if(window.ActiveXObject){    //如果是IE6.0之前的,那么那么采用ActiveXObject对象。
14         xhr = new ActiveXObject(‘Microsoft.XMLHTTP‘);
15     }else{
16         return false;    //如果浏览器不支持该功能, 那么就阻止程序运行。
17     }
18
19
20     if(method === ‘POST‘){
21         xhr.open(‘POST‘,url,async);
22         xhr.setRequestHeader(‘Content-Type‘,‘application/x-www-form-urlencoded‘);//POST提交数据,专用头部
23         xhr.send(data);    //发送请求,并附加数据,如果没有数据,则为默认值,null
24     }
25
26     if(method === ‘GET‘){
27         (data)?‘‘:data = ‘‘;
28         xhr.open(‘GET‘,encodeURI(url+‘?‘+data),async);    //GET请求,通过URL附加数据传输。而通过编码,可以解决IE6/7在GET方式下传输中文参数出现乱码的情况。后台则可以通过 urldecode($_GET[‘a‘]) 进行解码
29         xhr.send(null);
30     }
31
32     xhr.onreadystatechange=function(){    //注册请求的回调函数。
33         if(xhr.readyState == 4 && xhr.status == 200){    //readyState 这个是请求的状态,4表示请求成功。 status表示响应应答或者数据传输的状态。200表示数据传输成功。
34             callback(xhr);
35         }
36     }
37
38
39 }

  · 后端代码 ·

1 <?php
2     $v1 = $_REQUEST[‘v1‘];
3     $v2 = $_REQUEST[‘v2‘];
4     echo ($v1+$v2);
5 ?>

  · 调用方式 ·

 1 elem.onclick=function(){
 2     ajaxGetData({
 3         url:‘index.php‘,
 4         method:‘get‘,
 5         data:‘v1=1&v2=2‘,
 6         async:true,
 7         callback:function(xhr){
 8             alert(xhr.responseText);
 9         }
10     });
11 };

 3.2 重点说明

· ActiveXObject
  ActiveX插件可以与微软的其它组件进行交换,包括这里我需要的微软自带的HTTP请求方法。
  new ActiveXObjcet(‘Microsoft.XMLHTTP‘) IE5.0+ 支持的HTTP请求方法。

· setRequestHeader
  该方法可以设置请求的头部信息,常用以post方式向一个动态网页文件提交数据时使用。这是因为PHP中的$_POST[‘key‘]方法,需要用到键值对的格式,因此必须声明请求的类型为: setRequestHeader(‘Content-Type‘,‘application/x-www-form-   urlencoded‘) 以表单提交数据的方式来发送数据到服务器。

· readyState && status
  readyState表示HTTP请求的运行状态,不论请求的数据是否找到,都会经历以下的过程:
    0 ---- 请求初始化,简历xhr对象。
    1 ---- 与服务器建立连接,open()方法已经成功调用。
    2 ---- 请求已经接收
    3 ---- 请求正在处理
    4 ---- 请求处理完成

   status 则表示了HTTP所请求数据的状态[常见的反馈码]:

    200 ---- 数据请求完成,已经可以使用。
    404 ---- 页面未找到。

· open

   功能:初始化请求的参数。
   格式:open(‘请求数据的方式‘,‘所要请求的页面URL‘,‘是否异步‘);
   说明:
      · 请求数据的方式:GET | POST
      · 是否异步:true(异步) | false(同步)
   * 如果存在setRequestHeader()方法,一定要把open()方法放在它之前的一行。

. send
   功能:发送请求。
   格式:send(params)
   代码示例:
    send(null)
    //在GET方式下用这种方式,因为参数会在open方法中附加在URL后进行传输。

  send(‘fname=神&lname=经病‘) 
    //在POST方式,用这种方式传输参数,但要记得使用setRequestHeader()方法。

. 同步与异步
   xmlHttpReq对象的open()方法第三个参数可以设置同步或异步的方式。
      true - 表示为异步,它不会等待服务器的执行完成。
     false - 表示同步,它会等待服务器执行完成,否则便会挂起程序,一直等待,一般不推荐是用同步的方式,不过对于一些小程序还是可以使用的。

· 使用时间戳或随机数来确保无缓存的请求数据
  //时间戳
   open(‘GET‘,‘index.php?t=‘+ new Date()*1,true);

  //随机数
   open(‘GET‘,‘index.php?m=‘+ Math.random(),true);

四、框架隐藏域

 4.1 基本概念

“框架隐藏域” 技术,现在主要用于文件上传时使用,因为AJAX技术,无法实现文件的上传。
  在AJAX技术提出之前,如果想实现无刷新的提交或改变数据,一般都是通过“框架隐藏域”来实现的。
“框架隐藏域”的基本思路就是:页面会有一个空白的Iframe,通过display:none进行隐藏,然后在数据需要改变时,通过指定iframe的src值,让其跳转到所要请求的页面。然后将值传输到后台,那么页面的刷新,也会在隐藏的iframe中进行,当前窗口页面并不会被刷新。最后父页面在去获取隐藏的iframe中的结果即可,这样,便实现了通过隐藏iframe方式来实现无刷新的数据提交或改变。

一般来说,通过iframe实现无刷新,主要有以下几种方法:

  将值作为url参数附加到iframe的src中。
  在iframe中放入一个表单,然后让iframe中的表单进行提交
  将父页面的表单元素的target值指定为iframe的name值。

而父页面获取隐藏iframe请求结果的方法,有以下几种:

  + 通过onload,或JQ的load方法读取改变后的iframe的值,切记一点是,onload事件一定要在iframe发生改变之前就要绑定。
  + 后台的结果是一段JavaScript代码,改代码会回调父页面的指定方法,并传输请求结果:
     echo ‘<script>callback(‘数据提交成功‘)</script>‘

4.2 后台写入脚本

  · 前端代码 ·

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5 </head>
 6 <body>
 7     <button>click</button>
 8     <iframe id="ifr" src="" style="display:none" frameborder="0"></iframe>
 9 </body>
10 </html>
11 <script>
12     var btn = document.getElementsByTagName(‘button‘)[0],
13         ifr = document.getElementById(‘ifr‘);
14     btn.onclick=function(){
15         ifr.src="index.php?v=success?"+new Date().getTime(); //加入时间戳
16     }
17 </script>

  · 后端代码 ·

1 <?php
2     $v = $_REQUEST[‘v‘];
3     echo ‘<script>alert("‘.$v.‘")</script>‘;
4 ?>

  

4.3 JS主动判断Iframe的改变

  · 前端代码 ·

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5 </head>
 6 <body>
 7     <button>click</button>
 8     <iframe id="ifr" src="" style="display:none" frameborder="0"></iframe>
 9 </body>
10 </html>
11     <script>
12         var btn = document.getElementsByTagName(‘button‘)[0],
13             ifr = document.getElementById(‘ifr‘);
14
15         function load(obj,fn){
16
17            obj.isloaded = false;
18            obj.onreadystatechange=function(){
19                 if(this.readyState == ‘complete‘){
20                     if(!this.isloaded){
21                         this.isloaded = true;
22                         fn && fn();
23                     }
24                 }
25             };
26             obj.onload=function(){
27                if(!this.isloaded){
28                    this.isloaded = true;
29                    fn && fn();
30                }
31             };
32
33         }
34
35         btn.onclick=function(){
36
37             load(ifr,function(){alert(ifr.contentWindow.document.body.innerHTML)});
38             ifr.src=‘index.php?‘+new Date().getTime()+‘&v=success‘;
39
40         };
41
42 </script>

  · 后端代码 ·

1 <?php
2     $v = $_REQUEST[‘v‘];
3     sleep(5);
4     echo ‘success‘;
5 ?>

4.4 表单提交数据实战

  · 前端代码 ·

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5 </head>
 6 <body>
 7     <form action="index.php"  method="post" target="MyIframe">
 8         <input type="text" name="v" />
 9         <input type="button" id="btn" value="SubMit" />
10     </form>
11     <iframe id="ifr" style="display:none" frameborder="0" name="MyIframe"></iframe>
12 </body>
13 </html>
14 <script>
15     var btn = document.getElementById(‘btn‘),
16         ifr = document.getElementById(‘ifr‘);
17
18     function load(obj,fn){
19
20        obj.isOpen = false;
21        obj.onreadystatechange=function(){
22             if(this.readyState == ‘complete‘){
23                 if(!this.isOpen){
24                     this.isOpen = true;
25                     fn &&  fn();
26                 }
27             }
28         };
29         obj.onload=function(){
30            if(!this.isOpen){
31                this.isOpen = true;
32                fn && fn();
33            }
34         };
35
36     }
37
38     btn.onclick=function(){
39         document.forms[0].submit();
40         load(ifr,function(){alert(ifr.contentWindow.document.body.innerHTML)});
41
42     };
43
44
45 </script>

  附:关于 load() 方法的说明,见:http://www.cnblogs.com/HCJJ/p/5493821.html

 

五、JQ 的 AJAX

 5.1 load()

load方法是JQ中最简单最常用的Ajax方法。它默认采用GET请求,使用异步的方式,常用于请求一些静态的资源,例如HTML文件,然后插入到指定的DOM中。
load方法也可以指定请求的参数与回调函数,一旦指定了请求参数,那么load方法则会采用POST方式请求页面。
一个完整的load方法使用格式:
  load(url,params,callback); 
  url : 是被请求页面的url地址。若请求的页面是一个html文件,那么可以在url后面空一个空格然后附加一个选择器,便可以指定返回的内容,
  params : 请求时传递的参数,如果参数是一个对象,那么load便会使用POST方式请求,如果参数是一组键值对格式的字符串,那么则会采用GET请求。
  callback(data,status,xhr) : 请求完成时的回调函数。需要注意的是load方法的回调函数,不论请求成功还是失败,只要请求完成就会触发。
  data : 请求完成的值。
  status : 请求的状态
  xhr : XMLHttpRequest对象。

示例:

1 $(‘div‘).load(‘news.html .para‘);    //附加选择器
2 $(‘div‘).load(‘index.php‘,‘v=v1‘)    //附加参数,GET请求
3 $(‘div‘).load(‘index.php‘,{v:‘v1‘}) //附加参数,POST请求
4 $(‘div‘).load(‘index.php‘,{v:‘v1‘},function(data){$(this).html(data)})

5.2 $.get()

$.get()方法使用GET方式来进行异步请求。
  $.get(url,params,callback) 
  params : 请求时传输的参数,可以是对象形式,也可以是一个序列化的字符串。
      对象格式:{v:‘v1‘}
      序列化的字符串:‘v=v1&v2=v2‘;
  callback(data,status,xhr) : 注意的是,该函数只会在请求成功后才会被触发。
示例:
     $.get(‘index.php‘,{v:‘v1‘},function(data){alert(data)})

5.3 $.post()

$.post()方法使用POST方式进行异步请求。
 $.post(url,params,callback);

5.4 $.getScript()

$.getScript()方法会通过GET方式去请求一个脚本文件,并执行脚本代码。
   $.getScript(url,callback); 
     url : 脚本文件的url
     callback(data,status):请求后的回调函数,data是脚本的内容,而status则是请求的状态。

5.5 $.getJson()

$.getJson()与$.getScript()方法相同,不过$.getJson()方法专门用于请求json文件。
   $.getJson(url,callback); 
     url : json文件的url
     callback(data):请求后的回调函数,data是响应的数据。

5.6 $.ajax()

$.ajax()方法是JQ中最底层的AJAX方法,上面所说的都是基于$.ajax进行实现的。
学习$.ajax()方法,我们可以从两个最基本点进行入手,就是属性与事件。

a. 常用的属性说明:

url:[str]:         指定请求页面的url。
type:[str]:        设置请求的方式,是get还是post。
dataType[str]:     设置期望的后台返回数据格式。JQ会根据你指定的dataType类型进行数据的解析,因此如果不确定数据类型,这个地方可以不填,默认为JQ自动判断。
data:[str | obj]:  指定传输到后台的数据参数。
async:[boolean]:   设置请求是同步方式还是异步方式,默认为异步。
global:[boolean]:  设置是否开启AJAX的全局事件。
timeout:[number]:  设置超时时间。一旦后台响应的时间超过timeout的值,那么AJAX就会跳转到error事件中,并且error事件中的xhr对象,会有一个statusText属性返回值为timeout。
		    error:function(xhr){
			if(xhr.statusText == ‘timeout‘){
				alert(‘请求超时,请重新在试!‘);
			}
		     }jsonp:[str] : 后台会根据该值或得回调函数名称。

b. 常用的事件说明:

complete:当AJAX请求完成后触发的事件。
success:当AJAX请求完成并且成功后触发的事件。
error:当AJAX请求失败后触发的事件。
beforeSend:在AJAX准备发送之前触发的事件。在该事件的处理程序中,可对当前AJAX的options做最后一次修改。
		beforeSend:function(event,xhr){
			xhr.type = ‘get‘;
			xhr.url = ‘xxx.php‘;
			event.success:function(){

			};
		}

c. 全局事件说明:

当页面上存在任何ajax请求的时候都将触发这些特定的全局ajax事件处理函数。
全局AJAX事件处理函数的注册与执行,都是有一个特定的顺序。

如图:

其中:ajaxSend、ajaxSuccess、ajaxError、ajaxComplete都可以被页面上所有的AJAX请求,而ajaxStart、ajaxStop则只会被触发一次。

示例代码:

 1 var start = 0,
 2     send = 0;
 3 $(document).ajaxStart(function(){
 4     start++;
 5 });
 6 $(document).ajaxSend(function(){
 7     send++;
 8 });
 9 $.ajaxSetup({‘async‘:false});
10 $.ajax({...}) //ajax1;
11 $.ajax({...}) //ajax2;
12
13 console.log(start);  // --> 1;
14 console.log(send);     // --> 2;

因为ajaxSart()会在页面上的第一个请求发起时触发,ajaxStop()则会在最后一个请求结束时触发,所以它们常常组合用于显示loading等待框等。用来处理一群ajax请求。

另外需要注意是:

  • 全局事件永远不会再跨域的脚本中运行,也不会再JSONP请求中运行。
  • 在jQuery1.8以上,所有的全局ajax事件处理函数必须绑定到document上,也就是$(document).ajaxEvent()
  • 只有在$.ajax()亦或$.ajaxSetup()中的globle设置成true才能使用ajax全局函数,false将不能使用。

  下面详细说明每个AJAX的全局事件:   

    · ajaxStart()   

  ajax的全局事件。ajax请求开始发送时执行。
  该事件处理函数不会被连续触发。
  格式:

1 $(document).ajaxStart(function(e){
2     if(e.type === ‘ajaxStart‘){
3         alert(‘ajax请求开始!‘);
4     }
5 });

         *  e: 事件对象。

      · ajaxSend()

  ajax的全局事件。ajax请求发送时执行。
  该事件处理函数会被连续触发。
  格式:  $(document).ajaxSend(function(e,xhr,opt){});

* e:事件对象。
* xhr:XMLHttpRequest对象。
* opt:ajax参数选项。

    · ajaxSuccess()

ajax的全局事件。ajax请求成功时执行。
该事件处理函数会被连续触发。
格式: $(document).ajaxSuccess(function(e,xhr,opt,res){});

* e:事件对象。
* xhr:XMLHttpRequest对象。
* opt:ajax参数选项。
* res:ajax请求后 response返回的值。

· ajaxError()

ajax的全局事件。ajax请失败时执行。
该事件处理函数会被连续触发。
格式: $(document).ajaxError(function(e,xhr,opt,exc){});

* e:事件对象。
* xhr:XMLHttpRequest对象。
* opt:ajax参数选项。
* exc:失败原因。常见值:Not Found

· ajaxComplete()

ajax的全局事件。ajax请失败时执行。
该事件处理函数会被连续触发。
格式: $(document).ajaxError(function(e,xhr,opt){});

* e:事件对象。
* xhr:XMLHttpRequest对象。
* opt:ajax参数选项。

· ajaxStop()

ajax的全局事件。ajax请求停止时执行。
格式:

1 $(document).ajaxStop(function(e){
2     if(e.type === ‘ajaxStop‘){
3         alert(‘ajax请求结束!‘);
4     }
5 });

d. $.ajaxSetup()

在JQ的AJAX中,还有一个$.ajaxSetup方法,它可以全局的设置AJAX的默认参数选项。
示例:

 1 $.ajaxSetup({
 2     url:‘index.php‘,
 3     type:‘post‘,
 4     dataType:‘json‘,
 5     error:function(){alert(‘error!!‘)}
 6 });
 7
 8 oBtn.onclick=function(){
 9     $.ajax({
10         success:function(){
11             alert(‘success‘);
12         }
13     });
14 }

5.7 自己封装的一个Ajax

  再AJAX基础上再次封装,目的是减少书写AJAX代码的冗余。

 1 function ajaxGetData(_url,_data,fn,_async){
 2     $.ajax({
 3         type:‘post‘,
 4         url:_url,
 5         async:!_async,
 6         dataType:‘json‘,
 7         data:_data,
 8         success:function(data){
 9             fn && fn(data);
10         },
11         error:function(){
12             alert(‘接口请求失败,失败地址:‘+ _url);
13         }
14     });
15 }

5.8 序列化

在以往使用AJAX结合表单向后台传输参数时,我们需要用JS一个一个寻找表单控件元素,然后再一一取值附加到AJAX请求上。这对只有少量字段的表单勉强还可以使用。但如果表单元素越来越复杂,再使用这种方法就显得缺乏弹性。
Jquery为了解决这一常用的操作,提供了以下几个简便的方法,它们分别可以序列化与JSON格式化form表单元素的值。
   serialize()  - 序列化表单元素的值。所谓的序列化,就是以k=v的键值对格式并通过&进行连接的字符串。
   serializeArray()  - 该方法并不会返回字符串的值。而是将表单元素的值序列化为一个Json格式的数据。
示例:

1 $(form).serialize(); //name1=v1&name2=v2
2 $(form).serializeArray(); //[{name:name1,v:v1},{name:name2,v:v2}]

而实现serialize方法的核心功能,则是JQ的$.param()。
 $.params() 方法,可以将一个普通的对象序列化成一个键值对格式的字符串返回。
示例: $.params({‘key‘:‘value‘}); // ‘key=value‘

六、JSONP

 6.1 JSONP的概念

JSONP(JavaScript Object Notaction With Padding) 就是采用JSON格式表示数据并由双方开发人员相互约定的一种数据传输方法,该协议并不是一种公开标准的协议。只是一个相互约定的使用方法。
JSONP主要是利用HTML - script标签可以跨域的特性来解决跨域数据的传输与交换。(实际上含有src属性的HTML标记,都是可以跨域的)。
JSONP的核心思路就是通过script标签去请求一个后台服务页面的地址。然后在该后台页面中,会调用前端HTML页面中的一个事先定义好的函数,并将处理的结果作为函数的参数一并传输过去。
对于script标签而言,它不论src指向的url是一个*.js的文件,还是其他格式的文件,例如.php或者.jsp等,只要这个url指向的文件能返回一个符合JavaScript语法与格式的字符串即可。

  JSONP的基本工作流程如图所示:

  JSONP的基本工作流程代码实现如下

  · 前端代码 ·

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Document</title>
 6 </head>
 7 <body>
 8
 9 </body>
10 </html>
11 <script src="http://hd.tzj.iwgame.com/js/jquery.min.js"></script>
12 <script>
13
14     function callback(v){
15         alert(v);
16     }
17
18
19 </script>
20 <script src="index.php"></script>

  · 后端代码 ·

<?php
    $v = isset($_REQUEST[‘v‘])? $_REQUEST[‘v‘] : ‘"xxx"‘;
    echo ‘callback(‘.$v.‘)‘;
?>

 6.2 自己封装的JSONP

掌握JSONP的概念与基本的使用方式后,那么我们便可以封装一个公用的JSONP方法,该方法可以将请求的需求参数,与回调函数名称传输给后台,让后台自动的去生成所要回调的函数与结果。减少前端与后台的每次沟通成本。
具体代码如下:

 1 function JSONP(params){
 2
 3     var url = params.url,
 4         data = params.data,
 5         fn = params.callback,
 6         oScript = document.createElement(‘script‘),
 7         hd = document.getElementsByTagName(‘head‘)[0],
 8         callback = ‘jsonp_‘+ new Date().getTime()%1e6;
 9
10     window[callback] = function(data){
11
12         oScript.parentNode.removeChild(oScript);
13         fn(data);
14         window[callback] = undefined;
15         try{delete window[callback];}catch(e){;}
16
17     };
18
19     oScript.src = url+‘?data=‘+ data + ‘&callback=‘ + callback;
20     hd.appendChild(oScript);
21
22 }

    使用方式如下:

1 JSONP({
2     ‘url‘:‘index.php‘,
3     ‘data‘:‘condition=lt30‘,
4     ‘callback‘:function(data){alert(data)}
5 });

    后台代码如下:

1 <?php
2     $fn = isset($_REQUEST[‘callback‘])? $_REQUEST[‘callback‘] : ‘‘;
3     $data = isset($_REQUEST[‘data‘])? $_REQUEST[‘data‘] : ‘‘;
4     if($fn){
5         echo ‘‘.$fn.‘("‘.$data.‘")‘;
6     }
7 ?>

 6.3 JQ的JSONP使用。

    接下来我们再看下,基于$.ajax()方法实现的JSONP请求。

1 $.ajax({
2     type:‘get‘,
3     url:‘index.php‘,
4     dataType:‘jsonp‘,    //指定期望的返回结果是一个JSONP
5     jsonp:‘callback‘,    //指定后台通过callback参数来接收到JQ自己创建的一个回调函数名称。
6     data:‘data=x‘,
7     success:function(data){alert(data)}
8 });

   

    最后我们再总结一下,JSONP请求与传统的AJAX请求的区别,帮我们更好的区分与认识这两种机制。
      1. AJAX是基于XMLHttpRequest的并被同源策略所限制,而JSONP则是基于Script标签,可跨域的数据交换协议。
      2. AJAX的核心是XMLHttpRequest,它是一个已经标准化的协议,而JSONP则是一种相互约定非公开的协议。

时间: 2024-10-29 07:09:40

JavaScript的jsonp的相关文章

javascript笔记——jsonp

上篇博客介绍了同源策略和跨域访问概念,其中提到跨域常用的基本方式:JSONP和CORS. 那这篇博客就介绍JSONP方式.  JSONP原理 在同源策略下,在某个服务器下的页面是无法获取到该服务器以外的数据的,但img.iframe.script等标签是个例外,这些标签可以通过src属性请求到其他服务器上的数据. 而JSONP就是通过script节点src调用跨域的请求. 当我们通过JSONP模式请求跨域资源时,服务器返回给客户端一段javascript代码,这段javascript代码自动调用

原生javascript实现jsonp的封装

JSONP即JSON with Padding.由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名.协议.端口)的资源.如果要进行跨域请求, 我们可以通过使用html的script标记来进行跨域请求,并在响应中返回要执行的script代码,其中可以直接使用JSON传递javascript对象. 这种跨域的通讯方式称为JSONP. 我们可以动态的去创建一个script标签,利用他的src属性没有跨域的限制来实现的,相当于我们引入一个js文件 附上源码: jsonp: funct

JavaScript实现jsonp&amp;&amp;CORS

(function (global) { var id = 0, container = document.head || document.getElementsByTagName('head')[0]; function jsonp(options) { if (!options || !options.url) return; var scriptNode = document.createElement("script"), url = options.url, data =

javascript 实现jsonp

jsonp原理其实也简单,虽然ajax不能跨域,但是通过src这个属性我们可以实现跨域,其实和我们引入第三方jquery调用它的方法一样的. html: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> &l

原生javascript里jsonp的实现原理

ajax不能跨域,jsonp可以跨域 跨域的核心思想: 调用(拿到的接口),定义(jsonp核心处理器)分别是不同的script标签里面进行跨script取数据(只有get方式进行取数据 ) jsonp传进来的数据是{url:'',data:{ cbName='cb',(根据接口制定的命名规范,有些事叫callback) wd='aaa', ......(之后的数据都要进行字符串拼接) },success:function(result){}} 一:设置默认状态(容错处理) json=json|

javascript实现jsonp跨域问题+原理

在工作中往往存在跨域的问题 ,跨域是什么概念就不在这里了,搜这类问题的肯定已经知道了.下面直接探讨jsonp跨域原理 jspon跨域原理: 1.动态创建一个script标签 var script = document.createElement("script"); 2.添加src属性,value也就是所谓的接口的写入(注:此处要返回的是一个回调函数callback:这里可以省略callback字段写成 script.src = "http://xxxx.com/?user=

javascript - 封装jsonp

jsonp牵扯到同源策略.跨域等问题,这里不细说了. 实现就是创建动态的script标签来请求后台地址: 示例: jsonp('xxx.php', { uid: 1 }, function (res) { console.log(res) }) 实例: jsonp('http://localhost/server.php', { uid: 1 }, function (res) { console.log(res) }) 1 function jsonp (url, params, callba

jsonp与cors跨域的一些理解(转)

CORS其实出现时间不短了,它在维基百科上的定义是:跨域资源共享(CORS )是一种网络浏览器的技术规范,它为Web服务器定义了一种方式,允许网页从不同的域访问其资源.而这种访问是被同源策略所禁止的.CORS系统定义了一种浏览器和服务器交互的方式来确定是否允许跨域请求. 它是一个妥协,有更大的灵活性,但比起简单地允许所有这些的要求来说更加安全. 而W3C的官方文档目前还是工作草案,但是正在朝着W3C推荐的方向前进. 简言之,CORS就是为了让AJAX可以实现可控的跨域访问而生的. 浏览器的同源策

【跨域】#001 JSONP原理解析【总结】

一.JSONP 是什么? 1.1 概念 JSONP(JSON with Padding)是资料格式 JSON 的一种"使用模式",可以让网页从别的网域要资料.由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server2.example.com 的服务器沟通,而 HTML 的 <script> 元素是一个例外. 利用 <script> 元素的开源策略,从其他域 动态的获取 数据,这就是JSONP.(让使用者利用 script