一、AJAX基礎(chǔ)知識?
什么是ajax?
async javascript and xml,異步的JS和XML
xml:可擴(kuò)展的標(biāo)記語言
作用是用來存儲數(shù)據(jù)的(通過自己擴(kuò)展的標(biāo)記名稱清晰的展示出數(shù)據(jù)結(jié)構(gòu))
ajax之所以稱之為異步的js和xml,主要原因是:當(dāng)初最開始用ajax實(shí)現(xiàn)客戶端和服務(wù)端數(shù)據(jù)通信的時(shí)候,傳輸?shù)臄?shù)據(jù)格式一般都是xml格式的數(shù)據(jù),我們把它稱之為異步j(luò)s和xml(現(xiàn)在一般都是基于JSONS格式來進(jìn)行數(shù)據(jù)傳輸?shù)模?/p>

異步的JS
這里的異步不是ajax只能基于異步進(jìn)行請求(雖然建議都是使用異步編程)這里的異步特指的是
"局部刷新"
局部刷新 vs 全局刷新
在非完全前后端分離項(xiàng)目中,前端開發(fā)只需要完成頁面的制作,并且把一些基礎(chǔ)的人機(jī)交互效果實(shí)現(xiàn)JS完成即可,頁面中需要動態(tài)呈現(xiàn)內(nèi)容的部分,都是交給后臺開發(fā)工程師做數(shù)據(jù)綁定和基于服務(wù)器進(jìn)行渲染的(服務(wù)器端渲染)
全局刷新:當(dāng)前頁面中哪怕只有一個(gè)部分的數(shù)據(jù)需要改變,都需要服務(wù)器端把整個(gè)頁面數(shù)據(jù)重新的渲染,最后客戶端瀏覽器整體刷新頁面看到最新的效果
【優(yōu)勢】
1、動態(tài)展示的數(shù)據(jù)在頁面的原代碼中可以看見 有利于SEO優(yōu)化推廣 有利于搜索引擎的收錄和抓取
2、從服務(wù)器端獲取的結(jié)果就已經(jīng)是最后要呈現(xiàn)的結(jié)果了,不需要客戶端做額外的事情,所以頁面加載速度快(前提是服務(wù)器端處理的速度夠快,能夠處理過來),所以類似于京東、淘寶這些網(wǎng)站,首屏數(shù)據(jù)一般都是經(jīng)由服務(wù)器端渲染的
【弊端】
1、如果頁面中存在需要實(shí)時(shí)更新的數(shù)據(jù),每一次想要展示最新的數(shù)據(jù),頁面都要重新的刷新一次,這樣肯定不行(例如:股票網(wǎng)站 實(shí)時(shí)更新)
2、都交給服務(wù)器端做數(shù)據(jù)渲染,服務(wù)器端的壓力太大,如果服務(wù)器處理不過來 頁面呈現(xiàn)的速度更慢
(所以京東、淘寶這類網(wǎng)站,除了首屏是服務(wù)器端渲染的,其它屏一般都是客戶端做數(shù)據(jù)渲染綁定)
3、這種模式不利于開發(fā)(開發(fā)效率低)
目前市場上大部分項(xiàng)目都是前后端完全分離的項(xiàng)目(也有非完全前后端分離的)前后端完全分離的項(xiàng)目,頁面中需要動態(tài)綁定的數(shù)據(jù)是交給客戶端完成渲染的
1、向服務(wù)器端發(fā)送ajax請求
2、把從服務(wù)器端獲取的數(shù)據(jù)解析處理,拼接成為我們需要展示的HTML字符串
3、把拼接好的字符串替換頁面中某一部分的內(nèi)容(局部刷新)頁面整體不需要重新加載,局部渲染即可
【優(yōu)勢】
1、我們可以根據(jù)需求,任意修改頁面中某一部分的內(nèi)容(例如實(shí)時(shí)刷新)整體頁面不刷新,性能好,體驗(yàn)好(所有表單驗(yàn)證、需要實(shí)時(shí)刷新的等需求都要基于AJAX實(shí)現(xiàn))
2、有利于開發(fā),提高開發(fā)效率
(1)前后端的完全分離,后臺不需要考慮前端如何實(shí)現(xiàn),前端也不需要考慮后臺用什么技術(shù),真正意義上實(shí)現(xiàn)了技術(shù)的劃分
(2)可以同時(shí)是行開發(fā):項(xiàng)目開發(fā)開始,首先制定前后端數(shù)據(jù)交互的接口文檔(文檔中包含了,調(diào)取了哪個(gè)接口或者哪些數(shù)據(jù)等協(xié)議規(guī)范)后臺把接口先寫好(目前很多公司也需要前端自己拿 node來模擬這些接口)客戶端按照接口調(diào)取即可,后臺再次去實(shí)現(xiàn)接口功能即可
【弊端】
1、不利于SEO優(yōu)化:第一次從服務(wù)器端獲取的內(nèi)容不包含需要動態(tài)綁定的數(shù)據(jù),所以頁面的源代碼中沒有這些內(nèi)容,不利于SEO收錄,后期通過JS添加到頁面中的內(nèi)容,并不會寫在頁面的源代碼中(是源代碼不是頁面結(jié)構(gòu))
2、交由客戶端渲染,首先需要把頁面呈現(xiàn),然后再能過JS的異步AJAX請求獲取數(shù)據(jù),然后數(shù)據(jù)綁定,瀏覽器再把動態(tài)增加的部分重新渲染,無形中浪費(fèi)了一些時(shí)間 沒有服務(wù)器端渲染頁面呈現(xiàn)速度快
二、基于原生JS實(shí)現(xiàn)AJAX
創(chuàng)建一個(gè)ajax對象
let xhr=new XMLHttpRequest();
不兼容IE6及更低版本瀏覽器 (用 IE6:ActiveXObject)
打開請求地址(可以理解為一些基礎(chǔ)配置,但是并沒有發(fā)送請求呢)
xhr.open([method],[url],[async],[username],[user password]) 后邊兩參數(shù)一般不用
監(jiān)聽ajax狀態(tài)改變,獲取響應(yīng)信息(獲取響應(yīng)頭信息、獲取響應(yīng)主體信息)
xhr.onreadystatechange=()=>{
if(xhr.readyState===4&&xhr.status===200){
let result=xhr.responseText;//獲取響應(yīng)主體中的內(nèi)容
}
}
發(fā)送ajax請求
xhr.send(null);(括號中傳遞的內(nèi)容就是請求主體的內(nèi)容)
分析第二步中的細(xì)節(jié)點(diǎn)
xhr.open([method],[url],[async],[username],[user password])
[AJAX請求方式]
1、get系列的請求(獲?。?br>
get
delete:從服務(wù)器上刪除某些資源文件
head:只想獲取服務(wù)器返回的響應(yīng)頭信息(響應(yīng)主體內(nèi)容不需要獲取)
2、post系列請求(推送)
post
put:向服務(wù)器中增加指定的資源文件
...
不管哪一種請求方式,客戶端都可以把信息傳遞給服務(wù)器,服務(wù)器也可以把信息返回給客戶端,只是get系列一般以獲取為主(給的少,拿回來的多)而post系列一般以推送為主(給的多,拿回來的少)
1)我們想獲取一些動態(tài)展示的信息,一般使用get請求,因?yàn)橹恍枰蚍?wù)器端發(fā)送請求,告訴服務(wù)器端我們想要什么,服務(wù)器端就會把需要的數(shù)據(jù)返回
2)在實(shí)現(xiàn)注冊功能的時(shí)候,我們需要把客戶輸入的信息發(fā)送給服務(wù)器進(jìn)行存儲,服務(wù)器一般返回成功還是失敗等狀態(tài),此時(shí)我們一般都是基于POST請求完成
get系列請求和post系列請求,在項(xiàng)目實(shí)戰(zhàn)中存在很多區(qū)別
1、get請求傳遞給服務(wù)器的內(nèi)容一般沒有post請求傳遞給服務(wù)器的內(nèi)容多
原因:get請求傳遞給服務(wù)器內(nèi)容一般都是基于"url地址問題傳遞參數(shù)"來實(shí)現(xiàn)的,而post請求一般都是基于"設(shè)置請求主體"來實(shí)現(xiàn)的
各瀏覽器都以自己的關(guān)于url最大長度的限制(谷歌:8kb、火狐:7kb、IE:2kb...)
超過限制長度的部分,瀏覽器會自動截取掉,導(dǎo)致傳遞給服務(wù)器的數(shù)據(jù)缺失
理論上post請求通過請求主體傳遞是沒有大小限制的,真實(shí)項(xiàng)目為了保證傳輸?shù)乃俾?,我們也會限制的,真?shí)項(xiàng)目中為了保證傳輸?shù)乃俾?,我們也會限制大小(例如:上傳的資料或者圖片我們會做大小的限制)
2、get請求很容易出現(xiàn)緩存
這個(gè)緩存不可控:一般我們都不需要,而post不會出現(xiàn)緩存(除非自己做特殊處理)
原因:get是通過url問號傳參傳遞給服務(wù)器信息,而post是設(shè)置請求主體;
設(shè)置請求主體不會出現(xiàn)緩存,但是url傳遞參數(shù)就會了

解決方案:

3、get請求沒有post請求安全(post也并不是十分安全,只是相對安全)
原因:還是因?yàn)間et是url傳參給服務(wù)器
有一種比較簡單的黑客技術(shù):url劫持,也就是可以把客戶端傳遞給服務(wù)器的數(shù)據(jù)劫持掉 導(dǎo)致信息泄露
url:請求數(shù)據(jù)的地址(API地址)真實(shí)項(xiàng)目中后臺開發(fā)工程師會編寫一個(gè)API文檔,在API文檔中匯總了獲取哪些數(shù)據(jù)需要使用哪些地址,我們按照文檔操作即可
sync:異步(sync同步)設(shè)置當(dāng)前ajax請求是異步的還是同步的,不寫默認(rèn)是異步(true)如果設(shè)置為false,則代表當(dāng)前請求是同步的
用戶名和密碼:這兩個(gè)參數(shù)一般不用,如果你請求的url地址所在的服務(wù)器設(shè)定了訪問權(quán)限,則需要我們提供可通行的用戶名和密碼才可以(一般服務(wù)器都是可以允許匿名訪問的)
分析第三步中的細(xì)節(jié)點(diǎn)
xhr.onreadystatechange=()=>{
if(xhr.readyState === 4 && xhr.status === 200){ // 狀態(tài)碼
let result=xhr.responseText;//獲取響應(yīng)主體中的內(nèi)容
}
}