AJAX入門
處理跨域的主要方法
- JSONP
- CORS
本文主要討論CORS解決AJAX因為瀏覽器同源策略不能跨域請求數據的問題。
1. JSONP
JSONP跨域可以參考下面這篇博客
JSONP跨域
2. CORS
關於CORS細節可以閱讀阮一峰的跨域資源共享 CORS 詳解。
跨域資源共享 CORS
- 跨域資源共享CORS(Cross-origin resource sharing)
CORS是一個W3C標準,全稱是"跨域資源共享"(Cross-origin resource sharing)。它允許瀏覽器向跨源服務器,發出XMLHttpRequest請求,從而解決了AJAX不能跨域請求的問題。
- CORS需要瀏覽器和服務器同時支持。
整個CORS通信過程,都是瀏覽器自動完成,不需要用戶參與。對於開發者來說,CORS通信與同源的AJAX通信沒有差別,代碼完全一樣。瀏覽器一旦發現AJAX請求跨源,就會自動添加一些附加的頭信息,有時還會多出一次附加的請求,但用戶不會有感覺。
因此,實現CORS通信的關鍵是服務器。只要服務器實現了CORS接口,就可以跨源通信。
CORS允許瀏覽器向跨源服務器,發出XMLHttpRequest請求,從而克服了AJAX只能同源使用的限制。
AJAX簡介
AJAX即“Asynchronous JavaScript and XML”(異步的JavaScript與XML技術)
AJAX 是一種用於創建快速動態網頁的技術。通過在後臺與服務器進行少量數據交換,AJAX 可以使網頁實現異步更新。這意味著可以在不重新加載整個網頁的情況下,對網頁的某部分進行更新。
XMLHttpRequest對象是瀏覽器提供的一個API,用來順暢地向服務器發送請求並解析服務器響應,當然整個過程中,瀏覽器頁面不會被刷新。
創建AJAX步驟:
1.創建XMLHttpRequest對象
var xhr = new XMLHttpRequest();
兼容各個瀏覽器的創建方法
function createRequest (){ try { xhr = new XMLHttpRequest(); }catch (tryMS){ try { xhr = new ActiveXObject("Msxm12.XMLHTTP"); } catch (otherMS) { try { xhr = new ActiveXObject("Microsoft.XMLHTTP"); }catch (failed) { xhr = null; } } } return xhr; }
2.準備請求
xhr.open(method,url,async);
- open() 的第一個參數是HTTP請求方法 - 有GET,POST,HEAD以及服務器支持的其他方法。 保證這些方法一定要是大寫字母,否則其他一些瀏覽器(比如FireFox)可能無法處理這個請求。
- 第二個參數是要作為請求發送目標的URL。
- 第三個參數是true或false,表示請求是異步還是同步。true是異步,默認true。
3.發送請求
xhr.send();
send() 方法的參數可以是任何你想發送給服務器的內容
4.處理響應
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
console.log(xhr.responseText);
}
}
- onreadystatechange :當處理過程發生變化的時候執行下面的函數
- readyState狀態值
- 0:請求未初始化。
- 1:正在加載) or (已建立服務器鏈接)
- 2:請求已發送,正在處理中(通常現在可以從響應中獲取內容頭)。
- 3:請求在處理中;
- 4:響應已完成。
responseText:服務器以文本字符的形式返回
responseXML:獲得 XML形式的響應數據
對象轉換為JSON格式使用JSON.stringify
json轉換為對象格式用JSON.parse()
返回值一般為json字符串,可以用JSON.parse(xhr.responseText)轉化為JSON對象
代碼實現如下:
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<button id="myButton">點我</button>
<script src="./main.js"></script>
</body>
</html>
JS
myButton=document.getElementById(‘myButton‘)
myButton.addEventListener(‘click‘,(e)=>{
let xhr=new XMLHttpRequest()
xhr.onreadystatechange=()=>{
if( xhr.readyState===4){
console.log("請求響應都完畢了")
if( xhr.status>=200&& xhr.status<300){
console.log("請求成功")
console.log(typeof xhr.responseText)//判斷返回數據的類型是String
console.log( xhr.responseText)
let string= xhr.responseText
let object=window.JSON.parse(string)
console.log(typeof object)
console.log(object)
}else if( xhr.status>=400){
console.log("請求失敗")
}
}
}
xhr.open(‘GET‘,‘/xxx‘)
xhr.send()
})
if(path===‘/xxx‘){
response.statusCode=200
response.setHeader(‘Content-Type‘, ‘text/json;charset=utf-8‘)
response.write(`
{
"note":{
"to":"xxx",
"from":"yyy",
"content":"hello"
}
}
`)
response.end()
}
當發送請求的時候,就會根據xml.open(‘GET‘,‘/xxx‘)
找到對應的請求路徑。在本文是找到/xxx
路徑,然後返回所請求的數據,在瀏覽器運行結果如下。
CORS跨域
關於CORS細節可以閱讀阮一峰的跨域資源共享 CORS 詳解。
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<button id="myButton">點我</button>
<script src="./main.js"></script>
</body>
</html>
JS
myButton.addEventListener(‘click‘,(e)=>{
let xhr=new XMLHttpRequest()
xhr.open(‘GET‘,‘http://jack.com:8002/xxx‘)
xhr.onreadystatechange=()=>{
if(xhr.readyState===4){
console.log("請求響應都完畢了")
if(xhr.status>=200&&xhr.status<300){
console.log("請求成功")
console.log(typeof xhr.responseText)
console.log(xhr.responseText)
let string=xhr.responseText
let object=window.JSON.parse(string)
console.log(typeof object)
console.log(object)
}else if(xhr.status>=400){
console.log("請求失敗")
}
}
}
xhr.send()
})
if(path===‘/xxx‘){
response.statusCode=200
response.setHeader(‘Content-Type‘, ‘text/json;charset=utf-8‘)
response.setHeader(‘Access-Control-Allow-Origin‘,‘http://blog1.com:8001‘)
response.write(`
{
"note":{
"to":"xxx",
"from":"yyy",
"content":"hello"
}
}
`)
response.end()
}
可以看到當代碼沒有下面這一行代碼時AJAX並不能跨域請求response.setHeader(‘Access-Control-Allow-Origin‘,‘http://blog1.com:8001‘)
的時候,結果如下
從結果可以看出,因為瀏覽器的同源策略,AJAX不能跨域請求
解決的辦法是添加response.setHeader(‘Access-Control-Allow-Origin‘,‘http://blog1.com:8001‘)
源碼下載:Github
AJAX入門