?? ?? ??Ajax技術(shù)用于實(shí)現(xiàn)“無需刷新頁面即可從獲得服務(wù)端數(shù)據(jù)”穷蛹。在Ajax出來前,只能用一些hack手段來實(shí)現(xiàn)不刷新頁面的數(shù)據(jù)更新昼汗。
?? ?? ??Ajax技術(shù)的核心是XMLHttpRequest(簡(jiǎn)稱XHR)肴熏。
1.XMLHttpRequest對(duì)象
?? ?? ??講了一下創(chuàng)建xhr對(duì)象。創(chuàng)建本來是沒什么好說的顷窒,但是IE7以下有些特別扮超,所以作者介紹了一些判斷來判斷去的代碼,用來兼容各瀏覽器蹋肮。
1.1 XHR的用法
?? ?? ??介紹了xhr對(duì)象怎么調(diào)用它的方法出刷,怎么傳參,怎么接收結(jié)果坯辩。
?? ?? ??其中我比較注意的幾點(diǎn):
?? ?? ??(1)xhr對(duì)象有readyState屬性馁龟,0未初始化 1啟動(dòng) 2發(fā)送 3接收 4完成。
?? ?? ??(2)xhr對(duì)象有readystatechange事件漆魔,可以監(jiān)聽坷檩。
?? ?? ??(3)xhr對(duì)象有abort方法可以調(diào)用,能取消異步請(qǐng)求改抡。調(diào)用后矢炼,readystatechange事件不再會(huì)觸發(fā),也不再允許訪問與響應(yīng)有關(guān)的對(duì)象屬性阿纤。
?? ?? ??(4)不建議重用xhr對(duì)象 (大概意思是建議每用一次新建一個(gè)句灌,用完一次就銷毀一個(gè))
1.2 HTTP頭部信息
?? ?? ??介紹了xhr對(duì)象與HTTP請(qǐng)求頭之間的一些交互
?? ?? ??摘抄幾點(diǎn):
?? ?? ??(1)xhr的setRequestHeader方法可以設(shè)置自定義的請(qǐng)求頭部信息。(應(yīng)在open方法調(diào)用之后欠拾、send方法調(diào)用之前設(shè)置)
?? ?? ??(2)xhr的getResponseHeader方法可以獲取響應(yīng)頭部信息
?? ?? ??(3)xhr的getAllResponseHeaders方法可以一次性取得一個(gè)包含所有頭部信息的長字符串
1.3 GET請(qǐng)求
?? ?? ??GET請(qǐng)求的參數(shù)是直接加到URI 末尾的胰锌。
?? ?? ??需要注意的是加到URI末尾的查詢字符串格式應(yīng)當(dāng)正確。
?? ?? ??查詢字符串中的參數(shù)和值應(yīng)使用encodeURIComponent進(jìn)行編碼藐窄。
1.4 POST請(qǐng)求
?? ?? ??POST請(qǐng)求的主體可以包含各種格式的數(shù)據(jù)资昧。
?? ?? ??調(diào)用xhr的send方法時(shí),傳入?yún)?shù)荆忍,即可指定POST請(qǐng)求的數(shù)據(jù)格带。
?? ?? ??使用POST請(qǐng)求時(shí),如想模擬表單提交刹枉,可指定請(qǐng)求頭Content-Type為application/x-www-form-urlencoded叽唱,然后給send方法傳入想提交的表單序列化后的字符串。
?? ?? ??POST請(qǐng)求消耗的資源比GET請(qǐng)求多嘶卧,發(fā)送相同的數(shù)據(jù)的情況下尔觉,GET請(qǐng)求速度比POST請(qǐng)求快,甚至可達(dá)到POST速度的兩倍芥吟。
2.XMLHttpRequest 2級(jí)
2.1 FormData
?? ?? ??FormData用于序列化表單侦铜,以及創(chuàng)建與表單格式相同的數(shù)據(jù)专甩。
?? ?? ??它的方便之處在于不用明確在xhr對(duì)象設(shè)置請(qǐng)求頭,xhr對(duì)象能夠識(shí)別send方法傳入的是FormData實(shí)例钉稍,自動(dòng)配置請(qǐng)求頭涤躲。
2.2 超時(shí)設(shè)定
?? ?? ??在open方法調(diào)用后、send方法調(diào)用前贡未,xhr.timeout=毫秒數(shù)种樱,可以設(shè)置超時(shí)時(shí)間。
?? ?? ??超時(shí)時(shí)俊卤,xhr的狀態(tài)可能已經(jīng)走到4嫩挤,但超時(shí)后,xhr對(duì)象不允許訪問status屬性消恍,所以在onreadystatechange回調(diào)中岂昭,訪問status屬性要加try catch邏輯。
2.3 overrideMimeType方法
?? ?? ??這個(gè)方法用于重寫xhr響應(yīng)的MIME類型狠怨,這樣可以由前端決定按什么格式處理響應(yīng)內(nèi)容约啊。
?? ?? ??注意要在send方法調(diào)用前調(diào)用。
3.進(jìn)度事件
?? ?? ??有6個(gè)進(jìn)度事件:loadstart(開始接收響應(yīng)數(shù)據(jù)時(shí)觸發(fā))佣赖,progress(接收響應(yīng)期間不斷觸發(fā))恰矩,error(請(qǐng)求發(fā)生錯(cuò)誤時(shí)觸發(fā))、abort(主動(dòng)取消后觸發(fā))憎蛤、load(接收到完整響應(yīng)數(shù)據(jù)時(shí)觸發(fā))外傅、loadend(在觸發(fā)load/abort/error/通信完成時(shí)觸發(fā))
3.1 load事件
?? ?? ??說了一些load事件回調(diào)函數(shù)的寫法,和瀏覽器差異蹂午。
?? ?? ??我搞不懂為什么它說“Firefox實(shí)現(xiàn)中引入了load事件栏豺,用以替代readystatechange事件”彬碱,所以到底還有沒有readystatechange事件6剐亍?
3.2 progress事件
?? ?? ??progress事件會(huì)給回調(diào)函數(shù)傳入一個(gè)參數(shù)event對(duì)象巷疼,
?? ?? ??event.target 就是xhr對(duì)象
?? ?? ??event.lengthComputable 表示進(jìn)度信息是否可用的布爾值
?? ?? ??event.position 表示已經(jīng)接收的字節(jié)數(shù)
?? ?? ??event.totalSize 表示根據(jù)響應(yīng)頭部Content-Length指定的字節(jié)數(shù)
?? ?? ??必須在open方法調(diào)用前添加onprogress事件回調(diào)晚胡。
4.跨源資源共享
?? ?? ??xhr實(shí)現(xiàn)ajax通信受限于跨域安全策略。CORS(跨域資源共享)是W3C的一個(gè)工作草案嚼沿,定義了在訪問跨域資源時(shí)估盘,瀏覽器和服務(wù)器應(yīng)該如何溝通。
?? ?? ??CORS的基本思想骡尽,就是使用自定義的HTTP頭部讓瀏覽器于服務(wù)器進(jìn)行溝通遣妥,從而決定請(qǐng)求或響應(yīng)應(yīng)該成功還是應(yīng)該失敗。
?? ?? ??請(qǐng)求頭Origin和響應(yīng)頭Access-Control-Allow-Origin兩邊對(duì)不成功攀细,瀏覽器就會(huì)駁回請(qǐng)求箫踩。
4.1 IE對(duì)CORS的實(shí)現(xiàn)
?? ?? ??略爱态。
4.2 其它瀏覽器對(duì)CORS的實(shí)現(xiàn)
?? ?? ??略。
4.3 Preflighted Requeusts
?? ?? ??就是平時(shí)抓包看到的預(yù)請(qǐng)求機(jī)制境钟。瀏覽器覺得請(qǐng)求不是簡(jiǎn)單請(qǐng)求锦担,就會(huì)向服務(wù)器驗(yàn)證是否允許前端發(fā)送這樣的請(qǐng)求。
4.4 帶憑據(jù)的請(qǐng)求
?? ?? ??跨域請(qǐng)求默認(rèn)不帶憑據(jù)(cookie慨削、HTTP認(rèn)證及客戶端SSL證明等)洞渔,但可以設(shè)置成帶的。
?? ?? ??如果服務(wù)端允許請(qǐng)求端帶憑據(jù)缚态,請(qǐng)求才會(huì)成功返回給JavaScript磁椒,不然不會(huì)返回。
4.5 跨瀏覽器的CORS
?? ?? ??略玫芦。
5.其它跨域技術(shù)
?? ?? ??介紹除了CORS以外的跨域技術(shù)
5.1 圖像Ping
?? ?? ??<img>可以從任何url加載圖像衷快,不用擔(dān)心是否同源。所以有了圖像ping姨俩,這是一種與服務(wù)器進(jìn)行單向的跨域通信的一種方式蘸拔,請(qǐng)求的數(shù)據(jù)是查詢字符串的形式,響應(yīng)的可以是任意內(nèi)容环葵。
?? ?? ??圖像ping常用于跟蹤用戶點(diǎn)擊頁面或動(dòng)態(tài)廣告曝光次數(shù)调窍。它的缺點(diǎn):1.只能發(fā)送GET請(qǐng)求 2.無法訪問服務(wù)器的響應(yīng)文本
?? ?? ??不知道為什么說“無法訪問服務(wù)器的響應(yīng)文本”,img的內(nèi)容不能搞出來的嗎张遭?邓萨?
5.2 JSONP
?? ?? ??JSONP是通過動(dòng)態(tài)script元素來實(shí)現(xiàn)的,使用時(shí)菊卷,為script元素指定一個(gè)跨域的url缔恳,當(dāng)加載完成后,加載到的代碼就開始運(yùn)行洁闰。
?? ?? ??一般大家是這么實(shí)現(xiàn)的:服務(wù)端返回一份js文件歉甚。這個(gè)js文件的內(nèi)容,是把一堆JSON字符串丟給一個(gè)函數(shù)扑眉。
?? ?? ??這個(gè)函數(shù)名字在請(qǐng)求端指定url的時(shí)候就拼接在url參數(shù)里了纸泄。
?? ?? ??服務(wù)端從url讀取到那個(gè)函數(shù)的名字(對(duì)它來說就是個(gè)字符串),然后拼接:函數(shù)名(要返回的JSON);這就是那個(gè)js文件的內(nèi)容了腰素。
?? ?? ??前端加載到j(luò)s以后自動(dòng)執(zhí)行:函數(shù)名(返回的JSON);
?? ?? ??當(dāng)然聘裁,這個(gè)函數(shù)也是前端已經(jīng)定義好的。
?? ?? ??通過這種協(xié)作弓千,服務(wù)端把數(shù)據(jù)給到了前端js衡便。
?? ?? ??它的優(yōu)點(diǎn)是可以訪問響應(yīng)文本,不像img拿不到響應(yīng)內(nèi)容。缺點(diǎn)是不安全镣陕,動(dòng)態(tài)script元素加載跨域的資源代碼征唬,如果這個(gè)代碼含有惡意代碼,就很不安全茁彭。
?? ?? ??https://blog.csdn.net/hansexploration/article/details/80314948 這博客講得比紅書清晰多了
5.3 Comet
?? ?? ??comet是建立在Ajax基礎(chǔ)上总寒,但是能讓服務(wù)器主動(dòng)向頁面推送數(shù)據(jù)的技術(shù)。
?? ?? ??有兩種實(shí)現(xiàn)方式理肺,一種是“長輪詢”摄闸,就是頁面先發(fā)送請(qǐng)求,服務(wù)端什么時(shí)候想推送了什么時(shí)候再響應(yīng)妹萨。
?? ?? ??第二種是“流”年枕,一個(gè)HTTP連接一直不結(jié)束生命周期,然后服務(wù)端時(shí)不時(shí)地再推一些內(nèi)容到前端乎完。對(duì)前端來說熏兄,xhr對(duì)象的readyState時(shí)不時(shí)地變成3(接收),每次變成3树姨,xhr.responseText都多了一些內(nèi)容摩桶。
5.4 服務(wù)器發(fā)送事件
?? ?? ??SSE(服務(wù)器發(fā)送事件),SSE API用于創(chuàng)建“能讓服務(wù)器主動(dòng)推送的HTTP連接”帽揪,這個(gè)API把短輪詢(最蠢的那種)硝清、長輪詢、HTTP流的實(shí)現(xiàn)都封裝成現(xiàn)成的方法了转晰,還能自動(dòng)在異常斷開時(shí)重連芦拿。
5.5 Web Socket
?? ?? ??不多說了,平時(shí)工作中也有用查邢。
?? ?? ??它使用的是另外的協(xié)議蔗崎,比HTTP協(xié)議好在發(fā)送的數(shù)據(jù)量少,開銷少扰藕。
5.6 SSE 與 Web Sockets
?? ?? ??比較兩者優(yōu)劣缓苛。略。
6.安全
?? ?? ??分析了安全性实胸。略他嫡。
?? ?? ??最后:關(guān)于Ajax想要完整了解的話,話題非常龐大庐完,有專門討論Ajax的書,比如《Ajax高級(jí)程序設(shè)計(jì)》