2018-9-9-03關於ajax(這好像是第三次總結了)
阿新 • • 發佈:2018-11-10
-
什麼是ajax(前後端分離和不分離的優勢弊端)
ajax基礎知識 什麼是ajax? async javascript and xml ,非同步的js和xml xml:可擴充套件的標記語言 作用是用來儲存資料的(通過自己的擴充套件的標記名稱清晰的展示出資料結構) ajax之所以稱之為一步的js和xml,主要原因是:當初最開始使用ajax 實現客戶端和伺服器端資料通訊的時候,傳輸的資料格式一般都是xml格式的資料 ,所以稱之為非同步js和xml(現在一般都是基於json格式來進行資料傳輸的) 非同步的js 這裡的非同步不是說ajax只能基於非同步進行請求(雖然建議都使用非同步程式設計), 這裡的非同步特指的是“區域性重新整理” 區域性重新整理vs全域性重新整理 在非完全前後端分離專案中,前端開發只需要完成頁面的製作,並且把一些基礎的人機互動效果 ,使用js完成即可,頁面中需要動態呈現內容的部分,都是交給後臺開發工程師做資料繫結和基於 伺服器進行渲染的 【優勢】 1.動態展示的資料在頁面的原始碼中可以看見,有利於SEO優化推廣(有利於搜尋引擎的收錄和抓取) 2.從伺服器端獲取的結果就是最後要呈現的結果了,不需要客戶端做額外的事情,所以頁面載入速度快( 前提是伺服器端處理的速度夠快) 【弊端】 1.如果頁面存在需要實時更新的資料,每次想要展示最新的資料, 頁面都需要重新的重新整理一次 2.都交給伺服器端做資料渲染,伺服器端的壓力太大,如果伺服器處理不過來,頁面呈現的速度更慢 3.這種模式不利於開發(開發效率低) 目前市場上大部分專案都是前後端完全分離的專案 前後端完全分離的專案,頁面中需要動態繫結的資料是交給客戶端完成渲染的 1.向伺服器傳送ajax請求 2.把從伺服器端獲取的資料解析處理,拼接成為我麼需要的html字串 3.把拼接好的字串替換頁面中某一部分的內容(區域性重新整理),頁面整體不需要重新載入 區域性渲染即可 【優勢】 1.我們可以根據需求任意修改頁面中某一部分的內容(例如實時重新整理),整體頁面不重新整理,效能好,體驗好 (所有表單驗證,需要實時重新整理的等需求都要基於ajax實現) 2.有利於開發,提高開發效率 前後端完全分離,後臺不需要考慮前端如何實現,前端也不需要考慮後端用什麼技術,真正意義上實現了技術的劃分 可以同時開發:專案開發開始,首先指定前後端資料互動的文件介面(文件中包涵了調取哪個介面或者哪些資料等協議規範) 後臺先把介面寫好(目前很多公司也需要前端自己拿node來模擬這些介面),客戶端按照介面調取即可,後臺在此去實現介面功能即可 【弊端】 1.不利於SEO優化:第一次從伺服器端獲取的內容各種不好喊需要動態繫結的資料,所以頁面的原始碼中沒有這些內容, 不利於SEO收錄,後期通過js新增到頁面中的內容,並不會解除安裝頁面的原始碼中(是原始碼不是頁面結構) 2.交由客戶端渲染,首先需要把頁面呈現,然後再通過js的非同步ajax請求獲取資料,然後資料繫結,瀏覽器再把動態增加的 部分重新渲染,無形中浪費了一些時間,沒有伺服器段渲染頁面呈現速度
-
GET請求和POST請求的區別
基於原生js實現ajax 1.let xhr=new XMLHttpRequest() //不相容IE6及更低版本的瀏覽器(ie6:ActiveXObject) 2.xhr.open([method],[url],[async],[user name],[user password]) //開啟請求地址(可以理解成一些基礎配置,但並沒有傳送請求) 3.xhr.onreadystatechange=function(){ //監聽AJAX狀態改變,獲取響應資訊(獲取響應頭資訊,獲取響應主體資訊) if(xhr.readyState===4&&xhr.status===200){ let result=xhr.responseText; //獲取響應主體中的內容 } } 4.xhr.send(null) //傳送ajax請求(括號中傳遞的內容就是請求主體的內容) xhr.open([method],[url],[async],[user name],[user password]) [AJAX請求方式] 1.GET請求系列 get: delet://從伺服器上刪除某些資原始檔 head:只想獲取伺服器返回的響應頭資訊(響應主體的內容不需要獲取) ... 2.POST請求系列 post: put://向伺服器中增加指定的資原始檔 ... 不管哪一種請求方式,客戶端都可以把資訊傳遞給伺服器,伺服器也可以把資訊返回給客戶端 只是GET系列一般以獲取為主(給的少,拿回來的多),而post系列一般以同送為主(給的多,拿回來的少) 1.如果想獲取一些動態展示的資訊,一般使用get請求,因為只需要向伺服器傳送請求,告訴伺服器想要什麼 ,服務端就會把需要的資料返回 2.在實現註冊功能的時候,我們需要把客戶輸入的資訊傳送給伺服器進行儲存,伺服器一般返回成功還是失敗等狀態 此時一般基於POST請求完成 GET系列請求和POST系列請求,在專案實戰中存在很多的區別 1.GET請求傳遞給伺服器的內容一般沒有POST請求傳遞給伺服器的內容多 原因:GET請求傳遞給伺服器的內容一般都是基於url地址問號傳遞引數來實現的,而post請求一般都是基於 設定請求主體來實現的,各大瀏覽器都有自己的URL最大限制(谷歌:8kb,火狐:7kb,ie:2kb...) 超過長度的部分,瀏覽器會自動擷取掉,導致傳遞給伺服器資料丟失。 理論上post請求通過請求主體傳遞是沒有大小限制的,真實專案中為了保證傳輸的速率,我們也會限制大小(例如:上傳的資料或者 圖片我們會做大小的限制) 2.GET請求很容易出現快取(這個快取不可控:一般都不需要),而post不會出現快取(除非自己特殊處理) 3.GET請求沒有post請求安全(post也並不是十分安全,只是相對安全) url:請求資料的地址(API地址),後臺開發工程師會編寫一個api文件,在api文件中彙總了一些哪些資料需要使用哪些地址 async:非同步,設定當前ajax請求是非同步還是同步的,不寫預設是非同步(true),如果設定為false,則代表當前請求是同步的 使用者名稱和密碼:一般不用,如果請求的url地址所在的伺服器設定了訪問許可權,則需要提供可通行的使用者名稱和密碼才可以(一般伺服器都可以允許匿名訪問)
-
ajax狀態碼和網路狀態碼詳解
1.let xhr=new XMLHttpRequest() //不相容IE6及更低版本的瀏覽器(ie6:ActiveXObject) 2.xhr.open([method],[url],[async],[user name],[user password]) //開啟請求地址(可以理解成一些基礎配置,但並沒有傳送請求) 3.xhr.onreadystatechange=function(){ //監聽AJAX狀態改變,獲取響應資訊(獲取響應頭資訊,獲取響應主體資訊) if(xhr.readyState===4&&xhr.status===200){ let result=xhr.responseText; //獲取響應主體中的內容 } } 4.xhr.send(null) //傳送ajax請求(括號中傳遞的內容就是請求主體的內容) ajax狀態碼:描述當前ajax操作的狀態的 xhr.readyState 0:UNSENT 未傳送,只要建立了一個ajax物件,預設值就是0 1:OPEND 執行了xhr.open這個操作 2:HEADERS_RECEIVED 當前ajax的請求已經發送,並且已經接收到伺服器端換回的響應頭資訊了 3:LOADING 響應主體內容正在返回的路上 4:DONE響應主體內容已經返回到客戶端 HTTP網路狀態碼:記錄了當前伺服器返回資訊的狀態 xhr.status 200:成功,一個完整的HTTP事務完成(以2開頭的一般都是成功) 以3開頭的一般也是成功,只不過伺服器做了很多別的處理 301:永久轉移(永久重定向) 一般用於域名遷移 302:臨時轉移(臨時重定向,新的http版本307是重定向) 一般用於伺服器的負載均衡,當前伺服器處理不了,把當前請求臨時交給其他伺服器處理,一般圖片請求經常出現302 304:從瀏覽器快取中獲取資料 把一些不經常更新的檔案或者內容快取到瀏覽器中,下一次從快取中獲取,減輕伺服器壓力 以4開頭的,一般都是失敗,而且是客戶端的問題 400:請求引數錯誤 401:無許可權訪問 404:訪問地址不存在 以5開頭的,一般都是失敗,而且伺服器問題偏大 500:未知的伺服器錯誤 503:伺服器超負載
關於網路狀態碼 我的另一篇講的更詳細請求介面返回狀態碼
-
AJAX中的其他常用屬性和方法詳解
ajax中其他常用的屬性和方法
面試題:ajax中總共支援幾個方法?
let xhr = new XMLHttpRequest()
console.dir(xhr)
[屬性]:
。 readyState:儲存的是當前ajax的狀態碼
。 reasponse/responseText/responseXML:都是用來接收伺服器返回的響應主體中的內容
只是根據伺服器返回的格式不一樣,使用不同的屬性拉接收
。 responseText是最常用的,接收到的結果是字串格式的(一般伺服器返回的資料都是JSON格式字串)
。 responseXML偶爾會用到,如果伺服器返回的xml文件資料,就需要用這個屬性去接收
。 status:記錄了伺服器返回的http狀態碼
。 statusText:對返回狀態碼的描述
。 timeout:設定當前ajax請求的超時時間,假設設定的是3000ms,從ajax請求傳送開始,3秒後響應主體沒有返回,瀏覽器會把當前
ajax請求任務強制斷開
[方法]:
。abort():強制中斷ajax請求
。getAllResponseHeaders():獲取全部的響應頭資訊(獲取的結果是字串文字)
。getResponseHeader(key):獲取指定屬性名的響應頭資訊:例如:xhr.getResponseHeader("date")獲取響應頭中儲存的伺服器時間
。open():開啟一個url地址
。overrideMimeType():重寫資料的MIME型別
。send():傳送ajax請求(括號中書寫的內容是客戶端基於請求主體把資訊傳遞給伺服器)
。setRequestHeader(key,value):設定請求頭資訊(可以是設定的自定義請求頭資訊)
[事件]:
。onabort:當ajax被中斷請求是觸發這個事件
。onreadystatechange:ajax狀態發生改變觸發這個事件
。ontimeout:當ajax請求超時,會觸發這個事件
-
js中常用的內容編碼和加密解密方法
js中常用的編碼編碼解碼方法
正常的編碼解碼(非加密)
1.escape/unescape:主要是把中文漢字進行編碼和解碼的(一般只有js語言支援:也經常應用於前端頁面通訊的時候的漢字編碼)
2.encodeURI/decodeURI 基本上所有的程式語言都支援
3.encodeURIComponent /decodeURIComponent
需求:我們url問號傳遞引數的時候,引數值還是一個url或者包涵很多特殊字元,此時為了不影響主要的url
需要把傳遞的引數值進行編碼,使用encodeURI不能編碼一些特殊字元,所以只能使用encodeURLComponent處理
-
ajax中的同步和非同步程式設計
ajax任務:傳送請求接收到響應主體內容(完成 一個完整的http事務)
let xhr=new XMLHttpRequest();
xhr.open('get','temp.json',false)
xhr.onreadystatechange=()=>{
console.log(xhr.readyState)
}
xhr.send()
//只輸出一次 結果是4
let xhr=new XMLHttpRequest();
xhr.open('get','temp.json') //非同步程式設計這是
xhr.onreadystatechange=()=>{
console.log(xhr.readyState)
}
xhr.send()
//2 3 4
-
jq中的ajax詳解
$.ajax({
url:'',//設定請求api地址
method:'get',//請求方式get/post。。。在老版本中用的是type
dataType:'json',// datatype只是我們預設獲取結果的型別(期望的型別),不會影響伺服器的返回,伺服器一般給我們返回的都是json格式字串,
//如果我們預設的是json 那麼類庫中將把伺服器返回的字串轉換為json物件,如果預設的是text,我們把伺服器獲取的結果直接拿過來操作結果,我們預設的還可以是xml等
cache:false,//設定是否清楚快取,只對GET請求起作用,預設是true不清楚快取,手動設定為false,jq會在請求的url末尾會追加一個隨機數來清楚快取
data:null,//data可以把一些資訊傳遞給伺服器,get系列請求會把data中的內容拼接到url的末尾通過問號傳參的方式傳遞給伺服器
//post系列請求會把內容放在請求主體中傳遞給伺服器;data的值可以設定成兩種格式:字串和物件,如果是字串,設定的值時什麼傳遞給伺服器的就是什麼
//如果設定的是物件,jq會把物件變為xxx=xxx這樣的祖父穿傳遞給伺服器
async:true,//設定同步或者非同步,預設是true代表非同步
success:function(res){
//當ajax請求成功(readyState===4&&status是以2或者3開頭的)
//請求成功後jq會把傳遞的回撥函式執行,並且把獲取的結果當做實參傳遞給回撥函式
},
error:function(){
//請求失敗的回撥函式
},
complate:function(){
//不管是成功還是失敗都會執行 代表請求完成
}
})
-
封裝自己的ajax庫
<script>
~function(){
class ajaxClass{
//執行ajax
init(){
let xhr =new XMLHttpRequest()
xhr.onreadystatechange=()=>{
if(!/^[23]\d{2}$/.test(xhr.status)) return
if(xhr.readyState===4){
let result =xhr.responseText
switch(this.dataType.toUpperCase()){
case 'TEXT':
break
case 'HTML':
break
case 'JSON':
result=JSON.parse(result)
break
case 'XML':
result =xhr.responseXML
}
this.success(result)
}
}
if(this.data!==null){
this.farmatData()
if(this.isGET){
this.url+=this.querySymbol()+this.data
this.data=null
}
}
this.isGET?this.cache():null
xhr.open(this.method,this.url,this.async)
xhr.send()
}
farmatData(){
if(({}).toString.call(this.call)==="[object Object]"){
let obj=this.data
str=''
for(let key in obj){
if(obj.hasOwnProperty(key)){
str+=`${key}=${obj[key]}&`;
}
}
str=str.replace(/&$/g,'')
this.data=str
}
}
cacheFn(){
if(!this.cache){
!this.cache?this.url+=`${this.querySymbol()}_=${Math.random()}`:null
}
}
querySymbol(){
return this.url.indexOf("?")>-1?'&':'?'
}
}
//引數初始化
window.ajax=function({url=null,method='GET',type='GET',data=null,dataType='JSON',cache=true,async=true,success=null}={}){
let example= new ajaxClass()
example.url=url
example.method=type===null?method:type
example.data=data
example.dataType=dataType
example.cache=cache
example.async=async
example.success=typeof success ==='function'?success: new Function()
example.isGET=/^(get|delete|head)$/i.test(example.method)
example.init()
}
}()
</script>