axios入門(二)
阿新 • • 發佈:2020-08-05
XHR理解和使用
- 使用XMLHttpRequest(XHR)物件可以與伺服器互動,也就是傳送ajax請求
- 前端可以獲取到資料,而無需讓整個的頁面重新整理。
- 這使得Web可以只更新頁面的區域性,而不影響使用者的操作
區別一般http請求與ajax請求
- ajax請求是一種特別的http請求
- 對伺服器來說,沒有任何區別,區別在瀏覽器端
- 瀏覽器端傳送請求:只有XHR或fetch發出的才是ajax請求,其他的都是非ajax請求
- 瀏覽器端接收到響應
- 一般請求:瀏覽器一般會直接顯示響應體資料,也就是我們常說的重新整理/跳轉頁面
- ajax請求:瀏覽器不會對介面進行任何更新操作,只是呼叫監視的回撥函式並傳入響應相關資料
API
- XMLHttpRequest():建立XHR物件的建構函式
- status:響應狀態碼值,比如2000,404
- statusText: 響應狀態文字
- readyState:標識請求狀態的只讀屬性
0: 初始
1: open()之後
2: send()之後
3: 請求中
4: 請求完成 - onreadystatechange:繫結readyState給變的監聽
- responseType:指定響應資料型別,如果是‘json’,得到響應後自動解析響應體資料
- response: 響應體資料,型別取決於responseType的指定
- timeout: 指定請求超時時間, 預設為0 代表沒有限制
- ontimeout: 繫結超時的監聽
- onerror: 繫結請求網路錯誤的監聽
- open(): 初始化一個請求, 引數為: (method, url[, async])
- send(data): 傳送請求
- abort(): 中斷請求
- getResponseHeader(name): 獲取指定名稱的響應頭值
- getAllResponseHeaders(): 獲取所有響應頭組成的字串
- setRequestHeader(name, value): 設定請求頭
XHR的ajax封裝(簡單版axios)
特點
- 函式的返回值為promise,成功的結果為response,異常的結果為error
- 能處理多種型別的請求:GET/POST/PUT/DELETE
- 函式的引數為一個配置物件
{
url: '', // 請求地址
method: '', // 請求方式GET/POST/PUT/DELETE
params: {}, // GET/DELETE 請求的query 引數
data: {}, // POST 或DELETE 請求的請求體引數
}
- 響應json資料自動解析為js
編碼實現
<!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>使用XHR封裝ajax請求引數</title>
</head>
<body>
<button onclick="testGet()">傳送GET請求</button><br>
<button onclick="testPost()">傳送POST請求</button><br>
<button onclick="testPut()">傳送PUT請求</button><br>
<button onclick="testDelete()">傳送Delete請求</button><br>
<script>
/* 1. GET請求: 從伺服器端獲取資料*/
function testGet() {
axios({
// url: 'http://localhost:3000/posts',
url: 'http://localhost:3000/posts2',
method: 'GET',
params: {
id: 1,
xxx: 'abc'
}
}).then(
response => {
console.log(response)
},
error => {
alert(error.message)
}
)
}
/* 2. POST請求: 伺服器端儲存資料*/
function testPost() {
axios({
url: 'http://localhost:3000/posts',
method: 'POST',
data: {
"title": "json-server---",
"author": "typicode---"
}
}).then(
response => {
console.log(response)
},
error => {
alert(error.message)
}
)
}
/* 3. PUT請求: 伺服器端更新資料*/
function testPut() {
axios({
url: 'http://localhost:3000/posts/1',
method: 'put',
data: {
"title": "json-server+++",
"author": "typicode+++"
}
}).then(
response => {
console.log(response)
},
error => {
alert(error.message)
}
)
}
/* 2. DELETE請求: 伺服器端刪除資料*/
function testDelete() {
axios({
url: 'http://localhost:3000/posts/2',
method: 'delete'
}).then(
response => {
console.log(response)
},
error => {
alert(error.message)
}
)
}
/*
1.函式的返回值為promise, 成功的結果為response, 失敗的結果為error
2.能處理多種型別的請求: GET/POST/PUT/DELETE
3.函式的引數為一個配置物件
{
url: '', // 請求地址
method: '', // 請求方式GET/POST/PUT/DELETE
params: {}, // GET/DELETE請求的query引數
data: {}, // POST或DELETE請求的請求體引數
}
4.響應json資料自動解析為js的物件/陣列
*/
function axios({
url,
method='GET',
params={},
data={}
}) {
// 返回一個promise物件
return new Promise((resolve, reject) => {
// 處理method(轉大寫)
method = method.toUpperCase()
// 處理query引數(拼接到url上) id=1&xxx=abc
/*
{
id: 1,
xxx: 'abc'
}
*/
let queryString = ''
Object.keys(params).forEach(key => {
queryString += `${key}=${params[key]}&`
})
if (queryString) { // id=1&xxx=abc&
// 去除最後的&
queryString = queryString.substring(0, queryString.length-1)
// 接到url
url += '?' + queryString
}
// 1. 執行非同步ajax請求
// 建立xhr物件
const request = new XMLHttpRequest()
// 開啟連線(初始化請求, 沒有請求)
request.open(method, url, true)
// 傳送請求
if (method==='GET' || method==='DELETE') {
request.send()
} else if (method==='POST' || method==='PUT'){
request.setRequestHeader('Content-Type', 'application/json;charset=utf-8') // 告訴伺服器請求體的格式是json
request.send(JSON.stringify(data)) // 傳送json格式請求體引數
}
// 繫結狀態改變的監聽
request.onreadystatechange = function () {
// 如果請求沒有完成, 直接結束
if (request.readyState!==4) {
return
}
// 如果響應狀態碼在[200, 300)之間代表成功, 否則失敗
const {status, statusText} = request
// 2.1. 如果請求成功了, 呼叫resolve()
if (status>=200 && status<=299) {
// 準備結果資料物件response
const response = {
data: JSON.parse(request.response),
status,
statusText
}
resolve(response)
} else { // 2.2. 如果請求失敗了, 呼叫reject()
reject(new Error('request error status is ' + status))
}
}
})
}
</script>
</body>
</html>