AJAX(async JavaScript and XML),指的是通過 JavaScript 的非同步通訊,從伺服器獲取 XML 文件從中提取資料,再更新當前網頁的對應部分,而不用重新整理整個網頁。後來,AJAX 這個詞就成為 JavaScript 指令碼發起 HTTP 通訊的代名詞,也就是說,只要用指令碼發起通訊,就可以叫做 AJAX 通訊。W3C 也在2006年釋出了它的國際標準。
如何發請求?
瀏覽器與伺服器之間,採用 HTTP 協議通訊。使用者在瀏覽器位址列鍵入一個網址,或者通過網頁表單向伺服器提交內容,這時瀏覽器就會向伺服器發出 HTTP 請求。
我們還可以通過一些其他方式傳送請求。
<form>
標籤
用 form
可以發請求,但是會重新整理頁面或新開頁面
<form action="x" method=post>
<input type="username" name="username">
<input type="submit">
</form>
複製程式碼
當點選提交按鈕後,會發出一個post
的請求(在form
裡的method
裡面設定請求型別)。
在圖片中可以看到發出了一個路徑為x
的post
請求(路徑設定在form
的action
裡),請求的內容為username=123
,(usernam
在第一個input
標籤的name
裡設定,後面的類容是輸入框中的內容)。
<a>標籤
用 a
可以發 get
請求,但是也會重新整理頁面或新開頁面
<a href="x">點選</a>
複製程式碼
當點選按鈕之後,會發出一個get
請求。
<img>標籤
用 img
可以發 get
請求,但是隻能以圖片的形式展示
<script>
var image = document.createElement('img')
image.src = '/x'
document.body.appendChild(image)
</script>
複製程式碼
當定義一個img
標籤,設定了src
路徑之後,就會發出一個get
請求。當在頁面中引入這個img
標籤之後,只能以圖片的形式展示
<link>標籤
用 link
可以發 get
請求,但是隻能以 CSS
、favicon
的形式展示
<script>
var link = document.createElement('link')
link.rel = 'stylesheet'
link.href = '/x'
document.head.appendChild(link)
</script>
複製程式碼
link
標籤只有定義了並引入到頁面中之後,才會發出請求,(img
標籤只要定義之後就可以發請求)
<script>標籤
用 script
可以發 get
請求,但是隻能以指令碼的形式執行
<script>
var script = document.createElement('script')
script.src = '/x'
document.head.appendChild(script)
</script>
複製程式碼
當定義一個script
標籤並引入頁面之後,就會發出一個get
請求
進階
有沒有什麼方式可以實現
get
、post
、put
、delete
請求都行- 想以什麼形式展示就以什麼形式展示
AJAX
利用 AJAX 可以發出 HTTP 請求,得到伺服器返回的資料後,再進行處理。雖然 AJAX 的 X 代表著 XML ,但是目前伺服器返回的都是 JSON 格式的資料,AJAX 字面的含義已經消失了,已經成為了一個通用名詞。
具體來說,AJAX 包括以下幾個步驟。
- 建立
XMLHttpRequest
例項 - 發出
HTTP
請求 - 接收伺服器傳回的資料
- 更新網頁資料
一個AJAX請求
button.addEventListener("click", e => {
let request = new XMLHttpRequest();
request.open("GET", "/yyzcl"); //配置request
request.setHeader("yyzcl","OK"); //設定請求頭
request.send("Yyzcl");
request.onreadystatechange = () => {
if (request.readyState === 4) {
let string = request.responseText; // 獲取伺服器的返回值,是一個字串
let obj = window.JSON.parse(string); // 把符合JSON語法的字串轉換為JS對應的值(可以是物件,字串等)
}
};
});
複製程式碼
- 配置request
open
是用來配置request
的,其一共可以傳遞5個引數,來看看 MDN 的解釋。
void open(
DOMString method,
DOMString url,
optional boolean async,
optional DOMString user,
optional DOMString password
);
複製程式碼
第一個引數是請求方式,第二個引數是請求地址,後面的引數一般不改,使用預設設定,所以一般只設定兩個引數。
- 請求狀態
readyState
表示請求的狀態,其一共有5種狀態。
值 | 狀態 | 描述 |
---|---|---|
0 | UNSENT (未開啟) | open()方法還未被呼叫. |
1 | OPENED (未傳送) | open()方法已經被呼叫. |
2 | HEADERS_RECEIVED (已獲取響應頭) | send()方法已經被呼叫, 響應頭和響應狀態已經返回. |
3 | LOADING (正在下載響應體) | 響應體下載中; responseText中已經獲取了部分資料. |
4 | DONE (請求完成) | 整個請求過程已經完畢. |
從第二個值可以得到一個額外資訊,客戶端是分段下載響應體的。
AJAX解析
來看看之前那個 AJAX 請求。
button.addEventListener("click", e => {
let request = new XMLHttpRequest();
request.open("GET", "/yyzcl");
request.setHeader("yyzcl","OK");
request.send("Yyzcl");
request.onreadystatechange = () => {
if (request.readyState === 4) {
let string = request.responseText;
let obj = window.JSON.parse(string);
}
};
});
複製程式碼
open
是用來設定 HTTP 請求的第一部分的setHeader
是用來設定請求頭的第二部分的,第二部分有些資訊是瀏覽器自動設定的send
是用來設定請求頭的第四部分的,get
請求也可設定第四部分,不報錯,但不起作用
響應體解析
request.status
、request.statusText
是響應體的第一部分
request.getAllResponseHeaders()
或者request.getResponseHeader()
是響應體的第二部分
request.responseText
是響應體的第四部分
AJAX的同源政策
AJAX 只能向同源網址(協議、域名、埠都相同)發出 HTTP 請求,如果發出跨域請求,就會報錯
比如:
https://www.github.com
不能向http://www.github.com
傳送 AJAX 請求
http://github.com
不能向http://www.github.com
傳送 AJAX 請求
http://www.github.com:80
不能向http://www.github.com:81
傳送 AJAX 請求
CORS
CORS 是一個 W3C 標準,全稱是”跨域資源共享”(Cross-origin resource sharing)。它允許瀏覽器向跨源伺服器,發出XMLHttpRequest
請求,從而克服了 AJAX 只能同源使用的限制。
如果 A 想利用JavaScript
向 B 網站傳送 AJAX 請求,那麼只需要在 B 的後端寫上:
response.setHeader('Access-Control-Allow-Origin',' A 網站的 **協議** + **域名** + **埠號**')
就可以實現 AJAX 的跨域請求。
JSON
JSON(JavaScript Object Notation)是一種由道格拉斯·克羅克福特構想和設計、輕量級的資料交換語言,JSON 是 JavaScript 的一個子集,但 JSON 是獨立於語言的文字格式,並且採用了類似於C語言家族的一些習慣。
JSON
的資料格式有string
、number
、object
、array
、true
、false
、null
,和 JavaScript 還是有一些區別的。
JavaScript | JSON |
---|---|
undefined | 沒有 |
null | null |
['A','B']/["A","B"] | ["A","B"] |
function fn(){} | 沒有 |
{name: 'yyzcl'/"yyzcl"} | {"name": "yyzcl"} |
'yyzcl'/"yyzcl" | "yyzcl" |
var a={} | JSON沒有變數 |
{proto} | JSON沒有原型鏈 |