jsonp與ajax是兩種截然不同的請(qǐng)求方式洽胶,了解它們的原理塔橡,我們先了解什么是跨域图焰∑羰ⅲ跨域請(qǐng)求顧名思義就是請(qǐng)求超過自身域名空間的資源。舉個(gè)例子技羔,假如a.com的首頁index.html頁面里有一段js:
<script>
// jquery寫法
$.ajax({
Url: “http://b.com/getUserInfo”,
Method: “post”,
data: {
userId: “001”
},
success: function(res) {
console.info(res)
},
error: function(e) {
console.error(e)
}
})
</script>
當(dāng)你進(jìn)入a.com/index.html驰徊,這段js開始執(zhí)行,結(jié)果是報(bào)錯(cuò)的堕阔,因?yàn)槟惝?dāng)前的域名空間呢是a.com棍厂,而你去請(qǐng)求b.com的用戶數(shù)據(jù),跨域了超陆,瀏覽器由于安全限制是不允許js去請(qǐng)求跨域的數(shù)據(jù)(要是運(yùn)行牺弹,那銀行卡的用戶數(shù)據(jù)不就也可以請(qǐng)求了)浦马。
但是其實(shí)很多時(shí)候,我們需要跨域請(qǐng)求张漂,有兩種方式晶默,1種是代理(下次介紹node做獲取音樂數(shù)據(jù)),另外一種是用jsonp航攒。細(xì)心的程序員發(fā)現(xiàn)<script> <img><a>這一類的節(jié)點(diǎn)的src屬性不受域名限制磺陡,還是那個(gè)例子:
<html>
<head>
<script src=”http://b.com/getUserInfo”><!--改成用script標(biāo)簽請(qǐng)求剛才的接口-->
</head>
<body><body>
</html>
script標(biāo)簽可以請(qǐng)求到的getUserInfo接口返回的文本數(shù)據(jù),其實(shí)就是跟你引入jquery用了官網(wǎng)提供的cdn鏈接是一樣的
利用這個(gè)方式漠畜,我們可以這么寫:
a域名下的 index.html:
<script src =” b.com/getUserInfo?calk_back=’printer’ ”>
<script>
var printer= function(data) {
console.info(data)
}
</script>
b.com 域名下的getUserInfo接口返回文本:
printer("我是data")
上面一訪問 a.com/index.html,結(jié)果控制臺(tái)就會(huì)打印: 我是data
calk_back 參數(shù)名是前后端約定好的币他,后端根據(jù)這個(gè)參數(shù)的值printer,返回 printer(data)憔狞,這樣就把data傳入到 printer函數(shù)中
// 所以
<script src =” b.com/getData?call_back=printer”>
// 等于下面
<script>
printer(‘哈哈哈’)蝴悉; // data 是哈哈哈
</script>
而Ajax的底層是用XmlHttprequest類來實(shí)現(xiàn)異步請(qǐng)求(不刷新頁面就可以獲得響應(yīng)數(shù)據(jù)),所以不能跨域瘾敢,其原理為:
var request = new XmlHttprequest()
request.open(‘GET’, url, false) //fasle 說明這個(gè)是個(gè)異步請(qǐng)求
//下面指定回調(diào)函數(shù)
request.onreadystatechange = function(success_cb, error_cb){
// cb只是jquery指定進(jìn)來的
if ( request.readyState == 4 && request.status == 200 ) {
success_cb( xhr.responseText );
} else {
error_cb( xhr.statusText );
}
}
jQuery就是幫我們封裝成 $.ajax的工具來使用拍冠,各大瀏覽器為了安全,限制js跨域簇抵,所以ajax是不可以跨域的庆杜。Ajax由于太好用,已經(jīng)成為業(yè)界的標(biāo)準(zhǔn)碟摆,由H5出來后欣福,w3c也為此對(duì)Xmlhttprequest 提出出標(biāo)準(zhǔn)化,對(duì)xmlhttprequest增加新特性
- 可以設(shè)置HTTP請(qǐng)求的時(shí)限。
- 可以使用FormData對(duì)象管理表單數(shù)據(jù)(H5 formdata)焦履。
- 可以上傳文件。
- 可以請(qǐng)求不同域名下的數(shù)據(jù)(跨域請(qǐng)求雏逾,需要瀏覽器同意)嘉裤。
- 可以獲取服務(wù)器端的二進(jìn)制數(shù)據(jù)。
- 可以獲得數(shù)據(jù)傳輸?shù)倪M(jìn)度信息栖博。
大家可以看一下阮一峰大神的介紹: http://www.ruanyifeng.com/blog/2012/09/xmlhttprequest_level_2.html
現(xiàn)在屑宠,我們直接來封裝一個(gè)工具myRequest,能夠提供 jsonp與ajax兩種請(qǐng)求方式的工具
大家直接看代碼吧(圖片比代碼塊直觀哈):
提供get仇让、post兩個(gè)方法
起一個(gè)node 服務(wù):
訪問http://localhost:3000/, 返回index.html
當(dāng)他去請(qǐng)求百度的東西典奉,就跨域了
再來看看jsonp方法
我們拿QQ的接口來對(duì)看jsonp方法的執(zhí)行結(jié)果:
結(jié)果:jsonp獲取到數(shù)據(jù)
下一篇:《Ajax 文件上傳下載》
備注:等寫好把代碼鏈接貼出來