JS JSOP跨域請求實(shí)例詳解
在項(xiàng)目開發(fā)中遇到跨域的問題,一般都是通過JSONP來解決的。但是JSONP到底是個(gè)什么東西呢,實(shí)現(xiàn)的原理又是什么呢。在項(xiàng)目的空閑時(shí)間可以好好的來研究一下了。
1、什么是JSONP?
要了解JSONP,不得不提一下JSON,那么什么是JSON?
JSON is a subset of the object literal notation of JavaScript. Since JSON is a subset of JavaScript, it can be used in the language with no muss or fuss.
JSONP(JSON with Padding)是一個(gè)非官方的協(xié)議,它允許在服務(wù)器端集成Script tags返回至客戶端,通過javascript callback的形式實(shí)現(xiàn)跨域訪問(這僅僅是JSONP簡單的實(shí)現(xiàn)形式)。
2、JSONP有什么用?
由于同源策略的限制,XmlHttpRequest只允許請求當(dāng)前源(域名、協(xié)議、端口)的資源,為了實(shí)現(xiàn)跨域請求,可以通過script標(biāo)簽實(shí)現(xiàn)跨域請求,然后在服務(wù)端輸出JSON數(shù)據(jù)并執(zhí)行回調(diào)函數(shù),從而解決了跨域的數(shù)據(jù)請求。
JSONP的產(chǎn)生
1.眾所周知,Ajax請求資源受同域的限制,不管是靜態(tài)資源,動(dòng)態(tài)頁面,web服務(wù)都不行
2.同時(shí)我們發(fā)現(xiàn)web頁面上調(diào)用JS文件時(shí)則不受跨域的影響(不僅如此,我們還發(fā)現(xiàn)凡是擁有‘src'這個(gè)屬性的標(biāo)簽都擁有跨域的能力,比如<script>、<img>、<iframe>等)
3.可想而知,當(dāng)前階段如果想通過web端(ActiveX控件、服務(wù)器代理、HTML5的websocket等方式不算)跨域訪問數(shù)據(jù)就只有一種可能,那就是服務(wù)端把數(shù)據(jù)裝進(jìn)JS格式的文件里,供客戶端調(diào)用和處理
4.數(shù)據(jù)的傳輸,我們知道一種叫JSON的純字符數(shù)據(jù)格式可以簡潔的描述復(fù)雜的數(shù)據(jù)結(jié)構(gòu),而且還被JS原生支持,在客戶端可以很容易的處理這種格式的數(shù)據(jù)
5.這樣解決方案的一目了然了,web端通過和調(diào)用腳本一模一樣的方式,來調(diào)用跨域服務(wù)器上動(dòng)態(tài)生成的JS文件。服務(wù)器之所以要?jiǎng)討B(tài)生成JS文件,目的在于獲取客戶端的回調(diào)函數(shù)名并把客戶端需要的數(shù)據(jù)通過JSON(也可以是純字符串)的格式傳進(jìn)去
6.在客戶端對JS文件調(diào)用成功后,也就獲取到了回調(diào)函數(shù)里的參數(shù),剩下的就是對數(shù)據(jù)的處理了,這種方法和Ajax看起來很像,但是卻并不一樣(Jquery將JSONP和Ajax封裝在一起,如果不了解的人會(huì)混為一談)
7.為了便于客戶端使用數(shù)據(jù),逐漸形成了一種非正式傳輸協(xié)議,人們把它稱作JSONP,該協(xié)議的一個(gè)要點(diǎn)就是允許用戶傳遞一個(gè)callback參數(shù)給服務(wù)端,然后服務(wù)端返回?cái)?shù)據(jù)時(shí)會(huì)將這個(gè)callback參數(shù)作為函數(shù)名來包裹住JSON數(shù)據(jù),這樣客戶端就可以隨意定制自己的函數(shù)來自動(dòng)處理返回?cái)?shù)據(jù)了
好了,不知道大家對JSONP理解了沒有,如果沒有的話,鄙人就出來總結(jié)一下,說的不好,不要打我。
其實(shí)原理就是,客戶端請求一個(gè)鏈接,并把需要的參數(shù)加上,callback表示是一個(gè)JSONP的請求(這個(gè)前端和后臺可以自己統(tǒng)一),后臺解析這個(gè)請求鏈接,發(fā)現(xiàn)是一個(gè)JSONP的請求,然后生成一個(gè)調(diào)用方法,并根據(jù)請求參數(shù)動(dòng)態(tài)生成一個(gè)字符串(可以是JSON,也可以是純字符串)塞進(jìn)調(diào)用方法里,這樣客戶端就可以那到數(shù)據(jù)并做后續(xù)的處理了。
說了這么多,不上代碼不是我的風(fēng)格啊,上代碼。。
function test(data){ console.log(data) } var url="http://www.x.com/test?a=1&callback=test"http://向x.com/test傳遞參數(shù)a值為1,并告訴他要調(diào)用的函數(shù)名是“test” //后臺攔截到callback,知道要生成一個(gè)調(diào)用方法,方法名是test,并傳遞參數(shù),后臺處理生成如下(數(shù)據(jù)虛構(gòu)) test("aaaaaa") test({a:1,b:2}) //然后前端通過script標(biāo)簽去訪問并執(zhí)行,上面的東西 var script = document.createElement('script'); script.setAttribute('src', url); // 把script標(biāo)簽加入head,此時(shí)調(diào)用開始 document.getElementsByTagName('head')[0].appendChild(script); //然后就會(huì)調(diào)用頁面的test方法,這就是jsonp的實(shí)現(xiàn)原理。
關(guān)于Jquery中JSONP的現(xiàn)實(shí)
$.ajax({ type: "GET", url: "http://x.d.cn/asych/adv.html?loc=8&callBack=?",//告訴后臺這是一個(gè)jsonp請求,需要調(diào)用什么方法,如果為“?”,jq會(huì)幫你自動(dòng)生成(如果使用jq一般都設(shè)置為“?”,這樣才能在成功時(shí)觸發(fā)jq的回調(diào)函數(shù)) type:"post",//jsonp只能發(fā)get請求,就算我設(shè)置請求類型為post dataType:"jsonp",//告訴jquery這是一個(gè)jsonp的數(shù)據(jù),需要生成script標(biāo)簽來加載js data:{ a:"1" }, /*success: function (data) {//成功后jq會(huì)執(zhí)行的方法(如果callback參數(shù)為“?”) $("body").append(data); },*/ error: function (XMLHttpRequest, textStatus, errorThrown) { //alert(errorThrown); } }).done(function(data){ $("body").append(data); });
看了上面的代碼和注釋,相信大家都明白了吧,雖然Jquery將JSONP封裝到Ajax中,但是本質(zhì)上是不同的。
Ajax的核心是通過XmlHttpRequest獲取非本頁內(nèi)容,而JSONP的核心則是動(dòng)態(tài)添加<script>標(biāo)簽來調(diào)用服務(wù)器提供的js腳本。
所以Ajax和JSONP的區(qū)別不在于是否跨域,Ajax通過服務(wù)端代理一樣可以實(shí)現(xiàn)跨域,JSONP本身也不排斥同域數(shù)據(jù)的獲取。
還有上面說到過,JSONP和Ajax的數(shù)據(jù)格式不一定要是JSON,也可以是純字符串。
總而言之,JSONP不是Ajax的一個(gè)子集,即使Jquery將JSONP封裝進(jìn)Ajax,也不能改變這一點(diǎn)。
以上所述是小編給大家介紹的JS JSOP跨域請求實(shí)例詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
canvas實(shí)現(xiàn)簡易的圓環(huán)進(jìn)度條效果
本文主要分享了canvas實(shí)現(xiàn)簡易的圓環(huán)進(jìn)度條效果的實(shí)例,具有很好的參考價(jià)值,下面跟著小編一起來看下吧2017-02-02學(xué)習(xí)JavaScript設(shè)計(jì)模式之代理模式
這篇文章主要為大家介紹了JavaScript設(shè)計(jì)模式中的狀態(tài)模式,對JavaScript設(shè)計(jì)模式感興趣的小伙伴們可以參考一下2016-01-01微信 java 實(shí)現(xiàn)js-sdk 圖片上傳下載完整流程
這篇文章主要介紹了微信 java 實(shí)現(xiàn)js-sdk 圖片上傳下載完整流程的相關(guān)資料,需要的朋友可以參考下2016-10-10JS實(shí)現(xiàn)金額轉(zhuǎn)換(將輸入的阿拉伯?dāng)?shù)字)轉(zhuǎn)換成中文的實(shí)現(xiàn)代碼
這篇文章介紹了JS實(shí)現(xiàn)金額轉(zhuǎn)換(將輸入的阿拉伯?dāng)?shù)字)轉(zhuǎn)換成中文的實(shí)現(xiàn)代碼,有需要的朋友可以參考一下,希望對大家有用2013-09-09Javascript腳本實(shí)現(xiàn)靜態(tài)網(wǎng)頁加密實(shí)例代碼
這篇文章介紹了Javascript腳本實(shí)現(xiàn)靜態(tài)網(wǎng)頁加密實(shí)例代碼,有需要的朋友可以參考一下2013-11-11JS清除文本框內(nèi)容離開在恢復(fù)及鼠標(biāo)離開文本框時(shí)觸發(fā)js的方法
多網(wǎng)站的需要填寫的文本框在默認(rèn)狀態(tài)下都會(huì)給出一個(gè)默認(rèn)的提示語言,當(dāng)鼠標(biāo)點(diǎn)擊此文本框的時(shí)候能夠?qū)⒗锩娴哪J(rèn)文本清除,當(dāng)刪除輸入的文本且焦點(diǎn)離開文本框的時(shí)候再將默認(rèn)的文本寫入文本框2016-01-01js模擬如何實(shí)現(xiàn)重載以及默認(rèn)參數(shù)
這篇文章主要介紹了js模擬如何實(shí)現(xiàn)重載以及默認(rèn)參數(shù),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05