Ajax的基本原理是:XMLHttpRequest对象(简称XHR对象),XHR为向服务器发送请求和解析服务器响应提供了流畅的接口。能够以异步方式从服务器获得更多信息。意味着用户不必刷新页面也能取得新数据,然后通过DOM将数据插入到页面中。
XMLHttpRequest对象方法
about() : 停止当前的请求;
open("method","URL",[asyncFlag]) :启动请求
XHR的基本用法
在使用XHR对象时,要调用的第一个方法是 open() 方法,它有三个参数,第一个参数是:需要发送请求的类型( get 或者 post ),第二个参数是请求的 url ,第三个参数是请求的布尔值( true 是异步, false 是同步);
-
xhr.open('get','http://127.0.0.1/ajax/ajax.php',false) -
-
-
<div class="md-section-divider"></div>
如上代码会启动一个 get 请求 ajax.php ,但是请注意: open 方法并不会真正发请求,而只是启动一个请求以备发送;要发送真正请求必须使用 send() 方法;如下:
-
xhr.open('get','http://127.0.0.1/ajax/ajax.php',false); -
xhr.send(null); -
-
-
<div class="md-section-divider"></div>
send 的方法接收一个参数,需要请求发送的数据,如果请求不需要发送数据,需要传送一个 null ,因为对于有些浏览器这是必须的;上面第三个参数传的是 false ,是同步请求,服务器接收到响应后再继续执行后面的代码,响应后的数据会自动填充 XHR 对象的属性, XHR 有以下属性:
responseText : 作为响应主体被返回的文本。
responseXML : 如果响应的内容是”text/xml” 或 application/xml ,这个属性将保存包含响应数据的XML DOM文档;
status : 响应http状态;
statusText : http状态说明;
在接收到响应后,第一步是检查status状态,如果状态时 200 ,说明已经成功返回,此时 responseText 属性已经就绪;如果状态是 304 ,说明资源未被修改,可以直接使用浏览器缓存的版本,当然,响应是有效的;如下 ajax 请求代码:
-
// 创建xhr对象方法如下: -
function createXHR(){ -
var xhr; -
if (window.XMLHttpRequest){ -
// code for IE7+, Firefox, Chrome, Opera, Safari -
xhr=new XMLHttpRequest(); -
}else{ // code for IE6, IE5 -
xhr=new ActiveXObject("Microsoft.XMLHTTP"); -
} -
return xhr; -
} -
var xhr = createXHR(); -
xhr.open('get','http://127.0.0.1/ajax/ajax.php',false); -
xhr.send(null); -
if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) { -
console.log(xhr.responseText); -
}else { -
console.log(xhr.status); -
}
ajax.php代码如下:
-
<?php -
$data = json_decode(file_get_contents("php://input")); -
echo ('{"id" : ' . $data->id . ', "age" : 24, "sex" : "boy", "name" : "huangxueming"}'); -
?>
发ajax请求后,在控制台中打印如下:
说明已经请求成功;
上面的demo代码是同步请求,但是有时候我们需要发送异步请求,才能让 javascript 后续代码继续执行而不会堵塞,此时,我们可以检测 XHR 对象的 readyState 属性,该属性表示请求/响应当前活动阶段;这个属性取值如下:
- 0:未初始化。尚未调用open()方法;
- 1:启动。已经调用open()方法,但未调用send()方法;
- 2:发送。已经调用send()方法,但尚未接收到响应;
- 3:接收。已经接收到部分数据;
- 4:完成。已经接收到全部响应数据,而且可以在客户端使用了;
readyState 属性值由一个值变为另一个值,就会触发一次 readystatechange 事件。可以利用这个事件检测每次状态变化后的 readyState 值,但是必须在调用 open() 方法之前指定 onreadystatechange 事件;如下代码:
-
// 创建xhr对象方法如下: -
function createXHR(){ -
var xhr; -
if (window.XMLHttpRequest){ -
// code for IE7+, Firefox, Chrome, Opera, Safari -
xhr=new XMLHttpRequest(); -
}else{ -
// code for IE6, IE5 -
xhr=new ActiveXObject("Microsoft.XMLHTTP"); -
} -
return xhr; -
} -
var xhr = createXHR(); -
xhr.onreadystatechange = function(){ -
if(xhr.readyState == 4) { -
if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) { -
console.log(xhr.responseText); -
}else { -
console.log(xhr.status); -
} -
} -
} -
xhr.open('get','http://127.0.0.1/ajax/ajax.php',false); -
xhr.send(null);
如上代码,在处理onreadystatechange事件时使用了xhr对象,没有使用this对象,原因是onreadystatechange事件处理程序的作用域的问题;如果使用this对象,在有的浏览器下会执行失败,或者导致错误发生;
理解Http头部信息
每个http请求和响应都会带有响应的头部信息,xhr对象也提供了操作这两种头部(请求头部和响应头部的)信息的方法;
默认情况下,在发送XHR请求的同时,还会发送下列头部信息:
- Accept: 浏览器能够处理的内容类型;
- Accept-Charset: 浏览器能够显示的字符集;
- Accept-Encoding: 浏览器能够处理的压缩编码;
- Accept-Language: 浏览器当前设置的语言;
- Connection: 浏览器与服务器之间连接的类型;
- Cookie:当前页面设置的cookie;
- Host:发出请求页面所在的域;
- Referer:发出请求的页面url。
- User-Agent: 浏览器的用户代理字符串。
如下ajax.php请求所示:
我们还可以使用 setRequestHeader() 方法可以设置自定义的请求头部信息,这个方法接收2个参数:头部字段的名称和头部字段的值;要成功发送请求头部信息,必须在调用 open() 方法之后且调用 send() 方法之前调用 setRequestHeader() ;如下demo所示:
-
xhr.open('get','http://127.0.0.1/ajax/ajax.php',false); -
xhr.setRequestHeader("myHeader","myValue"); -
xhr.send(null);
截图如下:
调用 getAllResponseHeaders() 方法则可以取得一个包含所有头部信息的长字符串,如上代码中在 onreadystatechange 事件中添加 getAllResponseHeaders() 方法:
-
xhr.onreadystatechange = function(){ -
if(xhr.readyState == 4) { -
if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) { -
var myHeader = xhr.getAllResponseHeaders();; -
console.log(myHeader); -
}else { -
console.log(xhr.status); -
} -
}
打印如下:
理解GET请求
在ajax中,有常见的 get 请求或者 post 请求,使用 get 请求时,我们是把参数的名-值对经过 encodeURIComponent() 进行编码,然后放到URL的末尾,所有名值对必须由和好(&)分割;如下代码:
-
xhr.open('get','http://127.0.0.1/ajax/ajax.php?name1=value1&name2=value2',true);
下面我们可以封装一个方法可以辅助向现有的URL的末尾添加查询字符串参数;
-
function addURLParam(url,name,value) { -
url += url.indexOf("?") == -1 ? "?" : "&"; -
url += encodeURIComponent(name) + "=" + encodeURIComponent(value); -
return url; -
}
如下代码测试:
-
// 创建xhr对象方法如下: -
function createXHR(){ -
var xhr; -
if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari -
xhr=new XMLHttpRequest(); -
}else{ // code for IE6, IE5 -
xhr=new ActiveXObject("Microsoft.XMLHTTP"); -
} -
return xhr; -
} -
var xhr = createXHR(); -
xhr.onreadystatechange = function(){ -
if(xhr.readyState == 4) { -
if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) { -
var myHeader = xhr.getAllResponseHeaders();; -
console.log(myHeader); -
console.log(xhr.responseText); -
}else { -
console.log(xhr.status); -
} -
} -
} -
var url = "http://127.0.0.1/ajax/ajax.php"; -
url = addURLParam(url,"name1","value1"); -
url = addURLParam(url,"name2","value2"); -
xhr.open('get',url,true); -
xhr.setRequestHeader("myHeader","myValue"); -
xhr.send(null); -
function addURLParam(url,name,value) { -
url += url.indexOf("?") == -1 ? "?" : "&"; -
url += encodeURIComponent(name) + "=" + encodeURIComponent(value); -
return url; -
}
如下截图所示:
理解POST请求
Post 请求时作为请求的主体提交, post 请求的主体可以是非常多的数据,而且格式不限;在 open 方法的第一个参数传入 post ,就可以初始化 post 请求,如下:
-
xhr.open('post',"http://127.0.0.1/ajax/ajax.php",true)
接下来我们需要使用 send() 方法来发送数据,传入的参数可以是任何的字符串或者 form 表单序列化之后的数据;比如我们现在可以使用 xhr 来模仿表单提交数据,首先我们需要将 Content-Type 头部信息设置为 application/x-www-form-urlencoded , 也就是表单提交的内容类型,其次以适当的格式创建一个字符串,比如 form 表单序列化数据,然后通过 xhr 发送到服务器端,
如下 HTML 代码:
-
<form id="form"> -
<input name="user-name" value="aaa"/> -
<input name="user-email" value="233"/> -
</form>
JS代码如下:
-
// 序列化的代码 -
function serialize(form) { -
var arrs = [], -
field = null, -
i, -
len, -
j, -
optLen, -
option, -
optValue; -
for(i = 0,len = form.elements.length; i < len; i++) { -
field = form.elements[i]; -
switch(field.type) { -
case "select-one": -
case "select-multiple": -
if(field.name.length) { -
for(j = 0,optLen = field.options.length; j < optLen; j++) { -
option = field.options[j]; -
if(option.selected) { -
optValue = ''; -
if(option.hasAttribute) { -
optValue = option.hasAttribute("value") ? option.value : option.text; -
}else { -
optValue = option.attributes["value"].specified ? option.value : option.text; -
} -
arrs.push(encodeURIComponent(field.name) + "=" +encodeURIComponent(optValue)); -
} -
} -
} -
break; -
case undefined: //字段集 -
case "file": // 文件输入 -
case "submit": // 提交按钮 -
case "reset": // 重置按钮 -
case "button": // 自定义按钮 -
break; -
-
case "radio": // 单选框 -
case "checkbox": // 复选框 -
if(!field.checked) { -
break; -
} -
/* 执行默认动作 */ -
default: -
// 不包含没有名字的表单字段 -
if(field.name.length) { -
arrs.push(encodeURIComponent(field.name) + "=" +encodeURIComponent(field.value)); -
} -
} -
} -
return arrs.join("&"); -
} -
var url = "http://127.0.0.1/ajax/ajax.php"; -
xhr.open('post',"http://127.0.0.1/ajax/ajax.php",true); -
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); -
var form = document.getElementById("form"); -
xhr.send(serialize(form));
之后我们可以看到form表单序列化之后传过去的数据如下:
XMLHttpRequest 2级
XMLHttpRequest 1级 只是把已有的xhr对象的实现细节描述出来了,而 XMLHttpRequest 2级 是在原来的基础上增加了一些规范,但所有的浏览器只是实现了他规定的部分内容;如下几个:
理解FormData
现在web应用中频繁使用的一项功能是 form 表单序列化, XMLHttpRequest 2级 定义 了FormData 类型,使用 FormData 获取数据与表单序列化数据一样,但是更简洁方便;
支持 FormData 浏览器有:firefox4+, safari5+, chrome和Android3+版的webkit.
比如我现在提交form表单数据如下demo:
HTML代码:
-
<form id="form"> -
<input name="user-name" value="aaa"/> -
<input name="user-email" value="233"/> -
</form> -
-
-
<div class="md-section-divider"></div>
JS代码如下:
-
var url = "http://127.0.0.1/ajax/ajax.php"; -
xhr.open('post',"http://127.0.0.1/ajax/ajax.php",true); -
var form = document.getElementById("form"); -
xhr.send(new FormData(form)); -
-
-
<div class="md-section-divider"></div>
在chrome浏览器下如下:
在firefox浏览器如下:
使用 formData 的方便之处体现在不必明确地在 XHR 对象上设置请求头部,XHR对象能识别传入的数据类型是 FormData 实例,并配置适当的头部信息。
理解超时设定
IE8为 XHR 对象添加了一个 timeout 属性,表示请求在等待响应多少毫秒之后停止,在给 timeout 设置一个数值后,如果在规定的时间之内浏览器没有接受到响应,那么就会触发 ontimeout 事件,那么就会终止ajax请求,如下代码:
-
var url = "http://127.0.0.1/ajax/ajax.php"; -
xhr.open('get',"http://127.0.0.1/ajax/ajax.php",true); -
xhr.timeout = 1; -
xhr.ontimeout = function(){ -
alert("111"); -
}; -
xhr.send(null); -
-
-
<div class="md-section-divider"></div>
如上我把代码 timeout 设置1毫秒,如果请求1毫秒之后没有返回数据的话,就执行 ontimeout 事件,并且请求停止掉,目前我测试的浏览器chrome和firefox都支持;如下chrome浏览器截图如下:

进度事件
Progress Events规范是W3C的一个工作草案,定义了与客服端服务器通信有关的事件,这些事件最早是针对XHR操作的,有以下6个事件;
-
loadstart: 在接收到响应数据的第一个字节时触发; -
progress: 在接收响应期间持续不断的触发; -
error: 在请求发生错误时触发; -
abort: 在因为调用abort()方法而终止连接时触发; -
load:在接收到完整的响应数据时触发; -
loadend:在通信完成或者触发error,abort或load事件后触发;(这个事件基本上不使用的。)
支持前5个事件的浏览器有:firefox3.5+,safari4+,chrome,IOS版的safari和android版的webkit,opera(从11开始),IE8+只支持 load 事件;
load事件
Firefox在实现XHR对象的某个版本时,为了简化异步交互模型,实现了load事件,用以替代readystatechange事件,响应接收完毕后触发load事件,因此就没有必要检查readyState属性了;
目前支持的浏览器有:firefox,opera,chrome和safari
如下代码演示:
-
var xhr = createXHR(); -
xhr.onload = function(){ -
if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) { -
console.log(xhr.responseText); -
}else { -
console.log(xhr.status); -
} -
} -
xhr.open('get',"http://127.0.0.1/ajax/ajax.php",true); -
xhr.send(null); -
-
-
<div class="md-section-divider"></div>
progress事件
这个事件在浏览器接收数据期间周期性的触发,而 onprogress 事件处理程序会接收一个 event 对象,包含三个属性, lengthComputable 是一个表示进度信息是否可用的布尔值; position 表示已经接收的字节数, totalSize 表示根据 Content-Length 响应头部确定的预期总字节数。如下代码:
-
var xhr = createXHR(); -
xhr.onload = function(){ -
if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) { -
console.log(xhr.responseText); -
}else { -
console.log(xhr.status); -
} -
} -
xhr.onprogress = function(event) { -
var divStatus = document.getElementById("status"); -
if (event.lengthComputable){ -
divStatus.innerHTML = "Received " + event.position + " of " + -
event.totalSize +" bytes"; -
} -
}; -
xhr.open('get',"http://127.0.0.1/ajax/ajax.php",true); -
xhr.send(null); -
-
-
<div class="md-section-divider"></div>
截图运行如下:
跨源资源共享
通过 XHR 实现ajax通信的一个主要限制,来源于跨域安全策略。默认情况下, XHR 对象只能访问与包含它的页面位于同一个域中的资源,因为浏览器这样做的限制就是防止一些恶意操作;那么 CORS (跨源资源共享)的基本原理是:需要由服务器发送一个响应标头就可以让浏览器与服务器进行沟通;
比如我现在做一个demo来试着看,假如我现在在hosts文件下绑定2个IP地址:如下:
127.0.0.1 abc.example1.com
127.0.0.1 def.example2.com
那么现在我 abc.example1.com下有一个页面ajax.html,如下代码:
-
var xhr = createXHR(); -
xhr.onload = function(){ -
if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) { -
console.log(xhr.responseText); -
}else { -
console.log(xhr.status); -
} -
} -
xhr.open('POST',"http://def.example2.com/ajax/ajax.php",true); -
xhr.send(null); -
-
-
<div class="md-section-divider"></div>
如上代码,在给域下def.example2.com 下的ajax.php发ajax请求,因为是同源策略问题,肯定不成功,如下所示:
现在我们在def.example2.com域下php设置头部即可;如下代码:
-
header("Access-Control-Allow-Origin: *"); -
-
-
<div class="md-section-divider"></div>
ajax.php代码如下:
-
<?php -
header("Access-Control-Allow-Origin: *"); -
$data = json_decode(file_get_contents("php://input")); -
echo ('{"id" : ' . $data->id . ', "age" : 24, "sex" : "boy", "name" : "huangxueming"}'); -
?> -
-
-
<div class="md-section-divider"></div>
这样就可以认为大功告成,很高兴,看到书上或者网上查找资料后,也是这么说的,但是呢 当我再次请求这个页面的时候 http://abc.example1.com/ajax/ajax.html 还是发现因为同源策略的问题,请求不成功,查看控制台这样的错误,如下:
-
XMLHttpRequest cannot load http://def.example2.com/ajax/ajax.php. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://abc.example1.com' is therefore not allowed access. -
-
-
<div class="md-section-divider"></div>
也是同源策略的问题,不允许访问;继续通过网上查找资料,发现原来是我的 php.ini 里面的配置出了问题,在 php 安装目录下找到 php.ini 文件 output_buffering 默认为 off 的。我现在把它设为 on 就OK了。如下截图所示:

在php文件头部设置 header ,
-
header("Access-Control-Allow-Origin:*"); -
-
-
<div class="md-section-divider"></div>
星号意思是所有的请求都可以,但是设置并不安全,所以我们可以针对当前的这个页面域下设置,如下:
-
<?php -
header("Access-Control-Allow-Origin: http://abc.example1.com"); -
$data = json_decode(file_get_contents("php://input")); -
echo ('{"id" : ' . $data->id . ', "age" : 24, "sex" : "boy", "name" : "huangxueming"}'); -
?> -
-
-
<div class="md-section-divider"></div>
我们继续截图如下看看:
同样也可以访问;但是上面的在IE7-8下还是会报错,因为同源策略的问题,会报错,如下截图所示:
标准浏览器下比如chrome或者firefox不会报错,那么我们可以看下在IE下,IE如何实现对 CORS 的支持;
IE对CORS的实现方式如下:
微软在IE中引入XDR(XDomainRequest)类型,这个对象与XHR类似,但是能实现安全可靠的跨域通信,XDR对象部分实现了W3C的CORS规范;XDR与XHR不同之处如下:
- Cookie不会随请求发送,也不会随响应返回。
- 只能设置请求头部信息中的Content-Type字段。
- 不能访问响应头部信息。
- 只支持get和post请求。
这些变化使 CSRF(Cross-Site Request Forgery,跨站点请求伪造) 和 XSS(Cross-Site Scripting,跨站点脚本) 的问题得到了缓解,被请求的资源可以根据它认为合适的任意数据(用户代理,来源页面等)来决定是否设置 Accept-Control-Allow-Origin 头部。作为请求的一部分, Origin 头部的值表示请求的来源域,以便远程资源明确地识别 XDR 请求。
XDR 对象的使用方法与XHR对象非常相似,先创建一个 XDomainRequest 对象,如下:
-
var xdr = new XDomainRequest();
再调用 open() 方法,再调用 send() 方法;但是XDR对象的 open() 方法只接受2个参数,请求的类型和URL;
所有 XDR 的请求都是异步的,不能用来创建同步请求,请求成功后,会触发load事件,响应的数据保存在 responseText 属性中;如下demo,我们继续看下在IE7-8下如何可以跨域请求成功;如下代码:
-
var xdr = new XDomainRequest(); -
xdr.onload = function() { -
alert(xdr.responseText); -
}; -
xdr.open('POST',"http://def.example2.com/ajax/ajax.php",true); -
xdr.send(null);
现在我们刷新下页面可以看到请求成功了,如下所示:
如果响应失败的话,会调用error方法,通知开发人员,如下代码:
-
var xdr = new XDomainRequest(); -
xdr.onload = function() { -
alert(xdr.responseText); -
}; -
xdr.onerror = function(){ -
alert("响应失败"); -
}; -
xdr.open('POST',"http://def.example2.com/ajax/ajax.php",true); -
xdr.send(null);
与 XHR 一样, XDR 对象也支持 timeout 属性以及 ontimeout 事件处理程序,如下代码:
-
xdr.timeout = 1; -
xdr.ontimeout = function(){ -
alert("Request took too long."); -
};
请求超过1毫秒后没有响应,就调用ontimeout事件;
标准浏览器下实现对CORS的实现
其实实现方式在第一次讲解跨域的时候我们已经讲过了,可以翻到上面,但是我们现在重新来理一遍;
Firefox3.5+,Safari4+,chrome,ios版的safari和android平台中的webkit都通过 XMLHttpRequest 对象实现了 CORS 的原生支持;如下代码:
-
var xhr = new XMLHttpRequest(); -
xhr.onreadystatechange = function(){ -
if (xhr.readyState == 4){ -
if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) { -
alert(xhr.responseText); -
}else { -
console.log(xhr.status); -
} -
} -
} -
xhr.open('POST',"http://def.example2.com/ajax/ajax.php",true); -
xhr.send(null);
如上代码即可就可以实现在标准浏览器下ajax的跨域通信问题;
与IE中的XDR对象不同,通过跨域XHR对象可以访问 status 和 statusText 属性,而且还支持同步请求,跨域XHR对象也有一些限制,如下限制:
- 不能使用setRequestHeader()设置自定义头部;
- 不能发送和接收cookie。
- 调用getAllResponseHeaders()方法总会返回空字符串。
跨浏览器的CORS的实现
如上介绍的是对IE下和标准浏览器下2种方案实现跨域的实现方案,下面我们可以来封装下对常用的所有浏览器支持下,首先我们先检查是否存在 withCredentials 属性(标准浏览器下有这个属性),再结合检测 XDomainRequest 对象是否存在(就可以检测到IE),如下是所有封装的代码:
-
function createCORSRequest(method,url) { -
var xhr = new XMLHttpRequest(); -
if("withCredentials" in xhr) { -
xhr.open(method,url,true); -
}else if(typeof XDomainRequest != 'undefined') { -
xhr = new XDomainRequest(); -
xhr.open(method,url); -
}else { -
xhr = null; -
} -
return xhr; -
} -
var request = createCORSRequest('POST',"http://def.example2.com/ajax/ajax.php"); -
if(request) { -
request.onload = function(){ -
alert(request.responseText); -
} -
request.send(); -
}
浏览器支持程度:IE7+,firefox3.5+,safari4+,chrome3+等;
JSONP跨域技术的基本原理
Jsonp 跨域 get 请求是如何实现的;我们先来了解下为什么会出现跨域?
Javascript是一种在web开发中经常使用的前端动态脚本技术,在javascript中,有一个很重要的安全限制,被称为 same-Origin-Policy 同源策略,这一策略对于javascript代码能够访问的页面内容作了很重要的限制,即javascript只能访问与包含它的文档在同一域下的内容;
JSONP 的基本原理是:利用在页面中创建 <script> 节点的方法向不同域提交 http 请求的方法称为 JSONP 。
比如我现在的ajax.html页面 http://abc.example1.com/ajax/ajax.html 下提交ajax请求 http://def.example2.com/ajax/ajax.php get 请求,我们可以在ajax.html页面动态的创建 script 标签,如下:
-
var eleScript= document.createElement("script"); -
eleScript.type = "text/javascript"; -
eleScript.src = "http://def.example2.com/ajax/ajax.php"; -
document.getElementsByTagName("HEAD")[0].appendChild(eleScript);
当get请求从 http://def.example2.com/ajax/ajax.php 返回时,可以返回一断javascript代码,这段代码会自动执行,可以用来负责调用页面 http://abc.example1.com/ajax/ajax.html 中的一个callback函数;
理解 JSONP 执行过程如下:
首先在客户端注册一个 callback (比如 jsonpcallback ),然后把 callback 名字(比如叫 jsonp123456 )传给服务器端,服务器端得到 callback 名字后,需要用 jsonp123456() 把将要输出的 json 内容包括起来,此时,服务器生成的 json 数据才能被客户端正确接收;然后以javascript语法的方式,生成一个 function , function 的名字就是传递回来的参数 jsonp123456 .然后就可以在客户端直接运行调用 jsonp123456 这个函数了;
JSONP的优点:它不像 XMLHttpRequest 对象实现 ajax 请求受到同源策略的限制,它在所有的浏览器都支持,比如古老的IE6也支持,并且在请求完成后可以通过 callback 的方式传回结果;
JSONP的缺点:只支持 get 请求,不支持 post 请求,它只支持 http 跨域的请求情况,不能解决不同域的两个页面之间如何进行javascript调用的问题;
本文来自 龙恩0707 ,原文链接: 逐渐深入地理解Ajax ,如需转载,请注明原文出处。