Ajax 詳解及CORS
Ajax 是什麽?
Ajax 即“Asynchronous Javascript And XML”(異步 JavaScript 和 XML)是指一種創建交互式網頁應用的網頁開發技術。
它由以下幾種技術組合而成,包括:
- HTML/XHTML——主要的內容表示語言。
- CSS——為XHTML提供文本格式定義。
- DOM——對已載入的頁面進行動態更新。
- XML——數據交換格式。
- XSLT——將XML轉換為XHTML(用CSS修飾樣式)。
- XMLHttp——用XMLHttpRequest來和服務器進行異步通信,是主要的通信代理。
- JavaScript——用來編寫Ajax引擎的腳本語言。
在Ajax解決方案中,HTML/XHTML、DOM以及JavaScript是必須的。大概分為三個過程:
- 使用XMLHttpRequest發請求
- 服務器返回XML格式字符串
- JS解析XML並更新局部變量
XMLHttpRequest對象
當需要異步與服務器交換數據時,需要XMLHttpRequest對象來異步交換。XMLHttpRequest對象的主要屬性有:
- onreadystatechange——每次狀態改變所觸發事件的事件處理程序。
- responseText——從服務器進程返回數據的字符串形式。
- responseXML——從服務器進程返回的DOM兼容的文檔數據對象。
- status——從服務器返回的數字代碼,狀態碼如404(未找到)和200(已就緒)。
- status Text——伴隨狀態碼的字符串信息。
- readyState——對象狀態值。對象狀態值有以下幾個:
0 - (未初始化)還沒有調用send()方法
1 - (載入)已調用send()方法,正在發送請求
2 - (載入完成)send()方法執行完成
3 - (交互)正在解析響應內容
4 - (完成)響應內容解析完成,可以在客戶端調用了
對於readyState的狀態值,其中“0”狀態是默認狀態值,而對於成功訪問的狀態(得到信息)我們大多數采用“4”進行判斷
Ajax的核心就是是JavaScript對象XmlHttpRequest,這個對象為向服務器發送請求和解析服務器響應提供了流暢的接口。XmlHttpRequest可以使用JavaScript向服務器提出請求並處理響應,而不阻塞用戶。
XMLHttpRequest對象用法
XMLHttpRequest對象有兩個重要方法 open與send
let request = new XMLHttpRequest()
request.open(‘GET‘,‘/xxx‘) // 配置request
request.send()
open方法:
URL是相對於當前頁面的路徑,也可以似乎用絕對路徑。open方法不會向服務器發送真正請求,它相當於初始化請求並準備發送。只能向同一個域中使用相同協議和端口的URL發送請求,否則會因為安全原因報錯。
在發送同步請求的時候沒問題,只有得到響應後才會執行檢查status語句,但是在異步請求時,JavaScript會繼續執行,不等生成響應就檢查狀態碼,這樣我們不能保證檢查狀態碼語句是在得到響應後執行,這時候我們可以檢查request對象的readyState屬性,該屬性表示請求/響應過程中的當前活動階段,每當readyState值改變的時候都會觸發一次onreadystatechange事件。
request.onreadystatechange = function(){
if(request.readyState===4){
if(request.status>=200 && request.status<300){
let string = request.responseText
// 把符合 JSON 語法的字符串轉換成 JS 對應的值
let object = window.JSON.parse(string)
}else if(request.status >= 400){
console.log(‘說明請求失敗‘)
}
}
}
CORS(跨源資源共享)
CORS(Cross-Origin Resource Sharing)允許瀏覽器向跨源(協議 + 域名 + 端口)服務器,發出XMLHttpRequest請求,從而克服了AJAX只能同源使用的限制。
同源策略 : 只有協議+端口+域名 一模一樣的才允許發AJAX請求。AJAX可以讀取響應內容。
突破同源策略 === 跨域
CORS將導致跨域訪問的請求分為三種:Simple Request(請求沒有包含任何自定義請求頭),Preflighted Request(請求包含了任何自定義請求頭)以及Requests with Credential(跨域請求包含了當前頁面的用戶憑證)。
//響應頭用來記錄可以訪問該資源的域 ,它的值要麽是請求時Origin字段的具體值,要麽是一個*,表示接受任意域名的請求。
(‘Access-Control-Allow-Origin‘:,‘*‘)
原生 JS 寫出AJAX 請求
let request = new XMLHttpRequest()
request.open(‘get‘,‘/xxx‘)
request.send()
request.onreadystatechange = function(){
if(request.readyState===4){
if(request.status>=200 && request.status<300){
let string = request.responseText
let object = window.JSON.parse(string)
}else if(request.status >= 400){
console.log(‘說明請求失敗‘)
}
}
}
jQuery.ajax封裝代碼鏈接
window.jQuery = function(nodeOrSelector){
let nodes = {}
nodes.addClass = function(){}
nodes.html = function(){}
return nodes
}
window.$ = window.jQuery
window.jQuery.ajax = function({url,method,body,headers}){
return new Promise(function(resolve,reject){
let request = new XMLHttpRequest()
request.open(method,url)
for(let key in headers){
let value = headers[key]
requeq.setRequestHeader(key,value)
}
request.onreadystatechange = ()=>{
if(request.readyState===4){
if(request.status >=200 && request.status <300){
resolve.call(undefined,request.responseText)
}else if(request.status >= 400){
reject.call(undefined,request)
}
}
}
request.send(body)
})
}
myButton.addEventListener(‘click‘,(e)=>{
window.jQuery.ajax({
url: ‘/xxx‘,
method: ‘get‘,
headers:{
‘content-type‘:‘application/x-www-form-urlencoded‘,
‘frank‘: ‘18‘
},
}).then(
(text)=>{console.log(text)},
(request)=>{console.log(request)},
)
})
Ajax 詳解及CORS