摘要:就這樣被發(fā)明了,利用的屬性不受同源策略的控制,作弊般地巧妙地逃過了瀏覽器的這一限制。然后,聲明這個回調(diào)函數(shù)。
這是我在13年初寫的文章,當(dāng)時懵懵懂懂寫下了自己對JSONP的理解。
文章原文
博客 歡迎訂閱
提到JSONP,我當(dāng)時在網(wǎng)上找了無數(shù)帖子也沒有看懂它。那些文章大同小異,都是講到JSONP原理以后就戛然而止,把我們這些初學(xué)者搞得云里霧里。所以,寫下這篇文章,希望對大家有幫助!
為什么要有JSONP回答這個問題之前,大家先想想什么是AJAX,JSONP就是一種能夠解決AJAX辦不到的事情而存在的一種取數(shù)據(jù)的技術(shù)。什么事情是AJAX辦不到的呢?就是跨域!
跨域:顧名思義,就是當(dāng)前網(wǎng)頁的地址和我們要取的數(shù)據(jù)地址不在一個域下。這是因為瀏覽器都有一個“同源策略”— 兩個頁面的域名必須在同域的情況下,才能允許通信。
怎么才算一個域呢?
相同域名,相同端口,相同協(xié)議(因為不是這里的重點,大家可以請教Google)
“同源策略”的意義:“同源策略”有效地阻止了一些危險行為,比如你進入www.aaa.com,同時瀏覽器又開了一個www.bbb.com,如果這個www.bbb.com是一個木馬網(wǎng)站,在沒有“同源策略”的情況下,它就可能嵌入一些代碼,來取得你在www.aaa.com的信息(因為這時兩個頁面是可以通信的) 。而正是因為有了“同源策略”,剛才可以通信的情況才不會發(fā)生。
“同源策略”帶來的麻煩:上面的例子是我們在不知情的情況下,保護我們的網(wǎng)絡(luò)安全的,但如果我們就是要讓www.aaa.com取得www.bbb.com上的數(shù)據(jù),行不行呢?答:不行!還是因為”同源策略”!我們想從自己信任的網(wǎng)頁上取得數(shù)據(jù)都不行,這可怎么辦呢?
JSONP出現(xiàn)在需要跨域通信的歲月里,一些卓越的前端工程師們想到了這個”作弊”的辦法來逃避”同源策略”?!蓖床呗浴彪m然很厲害,阻止了一個頁面到另一個頁面的通信,可是src指向的路徑它放過了,提到src,大家是不是想起了?對,JSONP就是利用”同源策略”的這一”漏洞”來進行”作弊”的。(其實有src屬性的不止有,還有和,而也是能夠運用JSONP的)。
下面看看JSONP的原理:
JSONP:JSON with Padding,JSON大家這都知道,是一種數(shù)據(jù)通信格式,而”Padding”是什么意思,別急,往下看就知道了。
我們先舉一個簡單的例子:
www.aaa.com中:
www.bbb.com/abc.js中:
abc({"name":"risker","age":24});
頁面會彈出risker,有感覺了么?
JSONP是這樣工作的:像前面所說的那樣,我們可以取到www.bbb.com/abc.js,里面是一個abc函數(shù),這個函數(shù)也會被加載到www.aaa.com。加載完成后,就應(yīng)該執(zhí)行abc了,然后我們在www.aaa.com定義abc函數(shù),這個函數(shù)里寫一些處理數(shù)據(jù)的語句。這樣其實就簡單地實現(xiàn)了跨域訪問數(shù)據(jù)了,這也就是JSONP的原理了。而JSON with Padding的意思,就是abc(json)中的json:
abc({"name":"risker","age":24})。
這個JSON對象被包在abc這個函數(shù)中當(dāng)作參數(shù)來被處理,而JSON with Padding這個詞很形象地形容了這個過程。
JSONP的簡單實例在網(wǎng)上能找到的JSON基本只是介紹到這里就完了,但是這讓初學(xué)者看不到一個實實在在的例子。所以下面才是這篇文章和其他網(wǎng)上介紹JSON文章不一樣的地方,我?guī)Ыo大家一個例子!
大家一定對百度的自動搜索框有印象,它就是一個JSONP的實例:
先查看demo
分析一下:
1.分析數(shù)據(jù)地址回顧上面的例子,我們首先要知道數(shù)據(jù)的來源地址,就是上面的www.bbb.com/abc.js里的數(shù)據(jù)。在Chrome中查看Network。然后隨便在搜索框里輸入點什么,比如s,觀察Network里是不是多了東西,點開它,就是我們輸入“s”后傳回的數(shù)據(jù)了:
這個地址是http://suggestion.baidu.com/su?wd=S&p=3&cb=window.bdsug.sug&from=superpage&t=1365392859833 , 我們分析一下,wd后面是s,那就可以斷定百度定義wd是搜索的關(guān)鍵字,cb是一個回調(diào)函數(shù),其他的對我們就不重要了?;卣{(diào)函數(shù)是我們?nèi)〉綌?shù)據(jù)要后執(zhí)行的函數(shù),相當(dāng)于我們上面的abc函數(shù)。它是可以自己取名的。像http://suggestion.baidu.com/su?wd=S&p=3&cb=succ&from=superpage表示取到數(shù)據(jù)后執(zhí)行succ函數(shù):
這樣,我們的數(shù)據(jù)就包在了succ函數(shù)里做一個參數(shù),再次證明了JSON with Padding 的原理。
2.做標簽,其src指向數(shù)據(jù)地址:這是要動態(tài)生成的,不能把地址寫死,要不然取到的都是一樣的數(shù)據(jù)了。所以我們要動態(tài)生成,動態(tài)指定src屬性:
var oScript = document.createElement("script"); oScript.src = "http://suggestion.baidu.com/su?wd="+oTxt.value+"&p=3&cb=succ&from=superpage"; document.body.appendChild(oScript);
3.不要以為這樣問題就解決了,F(xiàn)12一下,就看到生成了好多!這是因為我們每輸入一個字符就動態(tài)生成一個,造成了代碼冗余!解決一下:
if(oScript){ document.body.removeChild(oScript); }
好,這樣,我們的搜索框效果就做好了,因為主要講JSONP部分的工作原理,就不做成百度下拉框那樣了,大家可以自己去布局。當(dāng)然,真正的百度搜索框還要在此基礎(chǔ)上涉及事件的冒泡取消等等,就不是這里的重點了,不做闡述。
JSONP總結(jié)JSONP是為了傳數(shù)據(jù)而存在的技術(shù)。網(wǎng)頁之間的通信原本有AJAX就夠了,而AJAX因為瀏覽器“同源策略”面對跨域情況就束手無策了。JSONP就這樣被發(fā)明了,利用的src屬性不受“同源策略”的控制,“作弊”般地巧妙地逃過了瀏覽器的這一限制。
JSONP方法本質(zhì)是創(chuàng)建標簽,其src指向我們的數(shù)據(jù)地址。地址后面附帶一個回調(diào)函數(shù)(名字一般是callback或者是別的什么,就看后臺給我們的是什么了,函數(shù)名是我們起的)。然后,聲明這個回調(diào)函數(shù)。這樣,只要一引入上面的標簽,就相當(dāng)于執(zhí)行了那個回調(diào)函數(shù)。
雖然jQuery把JSONP內(nèi)置在了AJAX里,但是我們一定要清楚,AJAX和JSONP是完全不一樣的,一定不要混淆!以后我會更新一篇介紹AJAX的文章的。
這里是前端和后臺的交匯之處,想要真正融會貫通,還要學(xué)學(xué)后臺的知識。我也是在學(xué)了PHP之后才把JSONP搞懂的。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/86001.html
摘要:使用的方法假設(shè)要在和頁面之間傳遞數(shù)據(jù)頁面頁面參考鏈接下面談一下跨域訪問的一些安全性問題,主要是和攻擊問題。在跨域訪問中,注入主要是參數(shù)注入,如防止措施是對參數(shù)進行校驗過濾。 所謂跨域,或者異源,是指主機名(域名)、協(xié)議、端口號只要有其一不同,就為不同的域(或源)。瀏覽器中有一個基本的策略,叫同源策略,即限制源自A的腳本只能操作同源頁面的DOM。 先聊一下w3c的CORS規(guī)范:CORS旨...
摘要:回調(diào)函數(shù)數(shù)據(jù)就是了,回調(diào)函數(shù)用來響應(yīng)應(yīng)該在頁面中調(diào)用的函數(shù),數(shù)據(jù)則用來傳入要執(zhí)行的回調(diào)函數(shù)。比如會得到小明這樣,里面的這個函數(shù)就能執(zhí)行并且得到數(shù)據(jù)了。 由于安全的原因,瀏覽器做了很多方面的工作,由此也就引入了一系列的跨域問題,需要注意的是: 跨域并非瀏覽器限制了發(fā)起跨站請求,而是跨站請求可以正常發(fā)起,但是返回結(jié)果被瀏覽器攔截了。最好的例子是 crsf 跨站攻擊原理,請求是發(fā)送到了后端服...
摘要:等到一段時間后,車到了,小紅打電話給小明車到了發(fā)布,小明在接到電話之后,要做一些準備訂閱時定義的回調(diào)函數(shù)。工作中的異步通過事件實例去做調(diào)控,簡單的代碼示例是一個事件實例,負責(zé)發(fā)布訂閱者的內(nèi)部實現(xiàn)訂閱發(fā)布另一端程序干一些事情。 淺談異步編程 引子 頁面渲染與setTimeout(); 同步與異步------我的理解 任務(wù)在當(dāng)次事件循環(huán)中阻塞后續(xù)任務(wù)進行的(指的是耗時較多,這個多少,暫時還...
摘要:解決異步編程有兩種主要方式事件模型和回調(diào)函數(shù)。將異步操作以同步操作的流程表達出來,避免了層層嵌套回調(diào)函數(shù)。方法是的別名,相當(dāng)于函數(shù)的第一個參數(shù)傳入,第二個參數(shù)傳入發(fā)生錯誤時的回調(diào)函數(shù)。 JavaScript 解決異步編程有兩種主要方式:事件模型和回調(diào)函數(shù)。但是隨著業(yè)務(wù)越來越復(fù)雜,這兩種方式已經(jīng)不能滿足開發(fā)者的需求了,Promise 可以解決這方面的問題。為了更好的理解 Promise ...
閱讀 2295·2023-04-25 23:15
閱讀 1961·2021-11-22 09:34
閱讀 1572·2021-11-15 11:39
閱讀 991·2021-11-15 11:37
閱讀 2180·2021-10-14 09:43
閱讀 3523·2021-09-27 13:59
閱讀 1529·2019-08-30 15:43
閱讀 3511·2019-08-30 15:43