Ajax
一、什么是 Ajax?
Ajax (Asynchronous JavaScript and XML) 是一種無需重新加載整個網頁的情況下,能夠更新部分網頁的技術。通過在后臺與服務器進行少量數據交換,Ajax 可以使網頁實現異步更新。
主要特性:
-
異步性 (Asynchronous):?可以在不阻塞用戶界面的情況下與服務器進行通信。
-
局部更新 (Partial Updates):?只更新網頁的一部分,而不是整個頁面,提高了用戶體驗。
-
基于標準:?Ajax 不是一種新技術,而是幾種現有技術的組合,包括JavaScript, XML, HTML, CSS。
二、Ajax 的核心對象:XMLHttpRequest
XMLHttpRequest
?(XHR) 對象是 Ajax 的核心。它允許瀏覽器在后臺與服務器進行通信。
三、基本語法和步驟 (XMLHttpRequest)
1.創建 XMLHttpRequest 對象:
let xhr;if (window.XMLHttpRequest) { // 現代瀏覽器xhr = new XMLHttpRequest();
} else { // IE6, IE5xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
2.配置請求 (open 方法):
xhr.open(method, url, async, username, password);
-
method
: HTTP 請求方法 (GET, POST, PUT, DELETE 等)。通常使用 GET 或 POST。 -
url
: 服務器端腳本的 URL。 -
async
: (可選) 布爾值,指示請求是否異步執行。 默認為?true
(異步)。 -
username
: (可選) 用于身份驗證的用戶名。 -
password
: (可選) 用于身份驗證的密碼。
xhr.open('GET', 'data.txt', true); // 異步 GET 請求
xhr.open('POST', 'submit.php', true); // 異步 POST 請求
3.設置請求頭 (可選):
xhr.setRequestHeader(header, value);
-
header
: 請求頭的名稱。 -
value
: 請求頭的值。
重要:?對于?POST
?請求,通常需要設置?Content-Type
?請求頭。
示例:
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); // 常用于 POST
xhr.setRequestHeader('Content-Type', 'application/json'); // POST 發送 JSON 數據
?4.發送請求 (send 方法):
xhr.send(body); // body 是要發送的數據
body
: (可選) 要發送到服務器的數據。
-
對于?
GET
?請求,通常?body
?為?null
。 數據應該附加到 URL 上(例如:url?param1=value1¶m2=value2
)。 -
對于?
POST
?請求,body
?可以是:-
null
?(如果沒有數據要發送) -
URL 編碼的字符串 (例如:
param1=value1¶m2=value2
) -
JSON 字符串 (需要設置?
Content-Type
?為?application/json
) -
FormData
?對象?
-
xhr.send(); // GET 請求,沒有數據
xhr.send('name=John&age=30'); // POST 請求,URL 編碼的數據
xhr.send(JSON.stringify({name: "John", age: 30})); // POST 請求,JSON 數據
5.處理服務器響應:
使用?onreadystatechange
?事件監聽?xhr.readyState
?的變化。
xhr.onreadystatechange = function() {if (xhr.readyState === 4) { // 請求完成if (xhr.status === 200) { // 請求成功// 處理響應數據let responseText = xhr.responseText; // 字符串形式的響應數據let responseXML = xhr.responseXML; // 如果服務器返回 XML,可以作為 XML 文檔訪問// 根據你的需求更新頁面等console.log("Response: " + responseText);} else {// 處理錯誤console.error("請求失敗,狀態碼:" + xhr.status);}}
};
-
xhr.readyState
: 表示請求的狀態。-
0: 請求未初始化
-
1: 服務器連接已建立
-
2: 請求已接收
-
3: 請求處理中
-
4: 請求已完成,且響應已就緒
-
-
xhr.status
: HTTP 狀態碼。-
200: "OK" (成功)
-
404: "Not Found" (未找到)
-
500: "Internal Server Error" (服務器內部錯誤) 等等。
-
四、示例
?1.完整的 GET 請求例子?
<!DOCTYPE html>
<html>
<head>
<title>簡單的 Ajax GET 請求</title>
</head>
<body><button onclick="loadData()">加載數據</button>
<div id="result"></div><script>
function loadData() {let xhr;if (window.XMLHttpRequest) {xhr = new XMLHttpRequest();} else {xhr = new ActiveXObject("Microsoft.XMLHTTP");}xhr.onreadystatechange = function() {if (xhr.readyState === 4) {if (xhr.status === 200) {document.getElementById("result").innerHTML = xhr.responseText;} else {document.getElementById("result").innerHTML = "Error: " + xhr.status;}}};xhr.open("GET", "data.txt", true);xhr.send();
}
</script></body>
</html>
?創建一個名為data.txt
的文件,內容例如:Hello, Ajax! This is data loaded from the server.
?2.完整的 POST 請求例子
<!DOCTYPE html>
<html>
<head>
<title>簡單的 Ajax GET 請求</title>
</head>
<body><button onclick="loadData()">加載數據</button>
<div id="result"></div><script>
function loadData() {let xhr;if (window.XMLHttpRequest) {xhr = new XMLHttpRequest();} else {xhr = new ActiveXObject("Microsoft.XMLHTTP");}xhr.onreadystatechange = function() {if (xhr.readyState === 4) {if (xhr.status === 200) {document.getElementById("result").innerHTML = xhr.responseText;} else {document.getElementById("result").innerHTML = "Error: " + xhr.status;}}};xhr.open("GET", "data.txt", true);xhr.send();
}
</script></body>
</html>
創建一個名為submit.php
的PHP文件(或者其他服務器端語言的文件),例如:
<?php$name = $_POST["name"];echo "你好, " . htmlspecialchars($name) . "!"; // 使用 htmlspecialchars 防止 XSS 攻擊
?>
五、使用 FormData 上傳文件
FormData
?對象提供了一種表示表單數據的鍵/值對的簡單方式,也可以用于上傳文件。
<!DOCTYPE html>
<html>
<head>
<title>Ajax 上傳文件</title>
</head>
<body><input type="file" id="fileInput"><br><br>
<button onclick="uploadFile()">上傳文件</button>
<div id="result"></div><script>
function uploadFile() {let xhr;if (window.XMLHttpRequest) {xhr = new XMLHttpRequest();} else {xhr = new ActiveXObject("Microsoft.XMLHTTP");}xhr.onreadystatechange = function() {if (xhr.readyState === 4) {if (xhr.status === 200) {document.getElementById("result").innerHTML = xhr.responseText;} else {document.getElementById("result").innerHTML = "Error: " + xhr.status;}}};const fileInput = document.getElementById("fileInput");const file = fileInput.files[0];const formData = new FormData();formData.append("file", file); // 添加文件到 FormDataxhr.open("POST", "upload.php", true);xhr.send(formData); // 不需要手動設置 Content-Type,瀏覽器會自動設置
}
</script></body>
</html>
創建一個名為upload.php
的PHP文件(或者其他服務器端語言的文件),例如:
<?php
if (isset($_FILES["file"])) {$file = $_FILES["file"];// 安全起見,你應該進行各種檢查,例如文件類型、大小等// 示例:$allowed_types = array("image/jpeg", "image/png", "application/pdf");if (!in_array($file["type"], $allowed_types)) {echo "Error: Invalid file type.";exit;}$upload_dir = "uploads/"; // 確保該目錄存在,并且有寫入權限$filename = basename($file["name"]); // 獲取文件名$target_path = $upload_dir . $filename;if (move_uploaded_file($file["tmp_name"], $target_path)) {echo "文件上傳成功!文件名: " . htmlspecialchars($filename);} else {echo "文件上傳失敗。";}} else {echo "沒有文件上傳。";
}
?>
Axios
一、什么是 Axios?
Axios 是一個基于?Promise
?的 HTTP 客戶端,用于瀏覽器和 Node.js。它允許開發者輕松地發送 HTTP 請求(GET、POST、PUT、DELETE 等),并處理服務器返回的響應。
為什么選擇 Axios?
-
基于 Promise:?可以使用 async/await,使異步代碼更易于編寫和理解。
-
瀏覽器和 Node.js 通用:?同樣的代碼可以在前后端運行。
-
自動轉換 JSON 數據:?自動將請求數據序列化為 JSON,并自動將響應數據反序列化為 JSON。
-
攔截器:?可以在請求發送前或響應接收后對數據進行處理(例如,添加認證 Token,處理通用錯誤)。
-
取消請求:?可以取消正在進行的請求。
-
客戶端支持防止 CSRF:?(通過 XSRF-TOKEN)。
-
文件上傳進度:?支持上傳和下載進度的監聽。
二、如何安裝和引入 Axios?
1. 在瀏覽器環境 (CDN):
直接在 HTML 文件中引入,引入后,axios
?對象會全局可用。
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
2. 在 Node.js 或前端項目 (npm/yarn):
npm install axios
# 或者
yarn add axios
import axios from 'axios'; // ES6 模塊
// 或者
const axios = require('axios'); // CommonJS 模塊
三、Axios 的基本用法和語法
Axios 提供多種方式來發起 HTTP 請求:
1. axios(config) 方法 (通用請求)
這是最通用的方式,通過傳入一個配置對象來定義請求。
axios({method: 'post', // 請求方法url: '/user/12345', // 請求 URLdata: { // POST 請求體數據 (會被自動序列化為 JSON)firstName: 'Fred',lastName: 'Flintstone'},headers: { // 請求頭'Content-Type': 'application/json','Authorization': 'Bearer YOUR_TOKEN'},timeout: 1000, // 請求超時時間,單位毫秒params: { // GET 請求參數 (會附加到 URL 后)ID: 12345}
})
.then(function (response) {console.log(response.data); // 服務器響應數據console.log(response.status); // HTTP 狀態碼console.log(response.headers); // 響應頭
})
.catch(function (error) {console.error(error); // 請求失敗或服務器返回非 2xx 狀態碼
});
2. 請求方法別名 (GET, POST, PUT, DELETE 等)
Axios 為常見的 HTTP 方法提供了便捷的別名方法。這些方法接受 URL 作為第一個參數,數據作為第二個參數(POST/PUT等),配置作為第三個參數。
GET 請求:axios.get(url, [config])
// 獲取用戶數據
axios.get('/user?ID=12345').then(response => console.log(response.data)).catch(error => console.error(error));// 或者通過 params 配置
axios.get('/user', {params: {ID: 12345},headers: {'X-Custom-Header': 'foobar'}
})
.then(response => console.log(response.data))
.catch(error => console.error(error));
?DELETE 請求:axios.delete(url, [config])
// 刪除用戶數據
axios.delete('/user/12345').then(response => console.log(response.data)).catch(error => console.error(error));
?POST 請求:axios.post(url, data, [config])
// 創建新用戶
axios.post('/user', {firstName: 'Fred',lastName: 'Flintstone'
})
.then(response => console.log(response.data))
.catch(error => console.error(error));// 例如上傳 FormData
const formData = new FormData();
formData.append('file', fileInput.files[0]);
formData.append('name', 'My Document');axios.post('/upload', formData, {headers: {'Content-Type': 'multipart/form-data' // 對于 FormData,通常瀏覽器會自動設置,但顯式寫明也沒錯}
})
.then(response => console.log(response.data))
.catch(error => console.error(error));
?PUT 請求:axios.put(url, data, [config])
// 更新用戶數據
axios.put('/user/12345', {age: 30
})
.then(response => console.log(response.data))
.catch(error => console.error(error));
其他方法:axios.head(url, [config]),
?axios.options(url, [config]),
axios.patch(url, data, [config])
用法與上述類似。
四、Axios 響應結構
無論請求成功與否,Axios 返回的 Promise 都會解析為一個響應對象。
成功響應 (在?.then()
?中收到):
{data: {}, // 服務器提供的響應數據status: 200, // HTTP 狀態碼statusText: 'OK', // HTTP 狀態信息headers: {}, // 響應頭config: {}, // 請求配置對象request: {} // 發出請求的 XMLHttpRequest 對象或 http.ClientRequest 實例
}
錯誤響應 (在?.catch()
?中收到):
// error 對象通常包含以下屬性:
{message: 'Error message', // 錯誤消息,例如 "Network Error"name: 'AxiosError', // 錯誤名稱code: 'ERR_BAD_REQUEST', // 錯誤碼,例如 ECONNABORTED (請求超時)config: {}, // 請求配置對象request: {}, // 發出請求的 XMLHttpRequest 或 http.ClientRequest 實例response: { // 如果服務器有響應 (即使是 4xx/5xx 狀態碼)data: {},status: 404,statusText: 'Not Found',headers: {},config: {},request: {}}
}
區分請求成功和服務器錯誤:
Axios 默認只將 HTTP 狀態碼為 2xx 的響應視為成功。其他狀態碼 (如 4xx, 5xx) 都會被視為錯誤,進入?.catch()
?塊。你可以在配置中修改這一行為:
axios.get('/some-data', {validateStatus: function (status) {return status >= 200 && status < 300 || status === 404; // 允許 2xx 或 404 狀態碼進入 .then()}
})
.then(response => { /* ... */ })
.catch(error => { /* ... */ });
五、Axios 實例 (創建自定義配置的實例)
當你的應用有多個不同配置的 API 地址或請求需求時,創建 Axios 實例非常有用。
const instance = axios.create({baseURL: 'https://some-domain.com/api/', // 基礎 URLtimeout: 5000,headers: {'X-Custom-Header': 'foobar'}
});// 使用實例發送請求
instance.get('/user/12345').then(response => console.log(response.data));instance.post('/another-endpoint', {message: 'Hello'
})
.then(response => console.log(response.data));
?所有通過?instance
?發送的請求都會繼承?instance
?的配置。