JavaScript發(fā)送HTTP請(qǐng)求的主要方法詳解
在Web開發(fā)中,JavaScript與服務(wù)器進(jìn)行數(shù)據(jù)交互是核心需求之一。從早期的原生AJAX到現(xiàn)代Fetch API,再到第三方庫如Axios,前端請(qǐng)求方案不斷迭代優(yōu)化。本文將詳細(xì)解析JavaScript發(fā)送請(qǐng)求的常用方法,幫助開發(fā)者根據(jù)場景選擇最適合的方案。
一、原生AJAX(XMLHttpRequest)
1. 基礎(chǔ)用法
XMLHttpRequest(XHR)是瀏覽器原生支持的異步請(qǐng)求技術(shù),通過創(chuàng)建對(duì)象并配置請(qǐng)求參數(shù)實(shí)現(xiàn)數(shù)據(jù)交互:
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data', true); // 異步請(qǐng)求
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(JSON.parse(xhr.responseText));
}
};
xhr.send();
2. POST請(qǐng)求示例
發(fā)送JSON數(shù)據(jù)時(shí)需設(shè)置請(qǐng)求頭并序列化參數(shù):
const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://api.example.com/submit', true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status === 201) console.log('創(chuàng)建成功');
else console.error('請(qǐng)求失敗:', xhr.statusText);
}
};
xhr.send(JSON.stringify({ name: 'Alice', age: 25 }));
3. 優(yōu)缺點(diǎn)分析
優(yōu)點(diǎn):兼容性好(IE6+支持),可監(jiān)聽上傳進(jìn)度(upload.onprogress)
缺點(diǎn):
- 代碼冗長,需手動(dòng)管理狀態(tài)
- 默認(rèn)不攜帶Cookie(需設(shè)置
xhr.withCredentials = true) - 跨域請(qǐng)求需后端配置
Access-Control-Allow-Credentials
二、Fetch API
1. 基礎(chǔ)用法
Fetch基于Promise實(shí)現(xiàn)更簡潔的異步操作:
fetch('https://api.example.com/data')
.then(response => {
if (!response.ok) throw new Error('Network error');
return response.json();
})
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
2. POST請(qǐng)求示例
fetch('https://api.example.com/submit', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'Bob', age: 30 }),
credentials: 'include' // 攜帶Cookie
})
.then(response => response.json())
.then(data => console.log(data))
.catch(console.error);
3. 高級(jí)特性
超時(shí)控制:通過AbortController實(shí)現(xiàn)
const controller = new AbortController();
setTimeout(() => controller.abort(), 5000);
fetch('https://api.example.com/data', { signal: controller.signal })
.catch(err => {
if (err.name === 'AbortError') console.log('請(qǐng)求超時(shí)');
});
流式響應(yīng):處理大文件時(shí)使用response.body.getReader()
4. 優(yōu)缺點(diǎn)分析
優(yōu)點(diǎn):語法簡潔,支持流式處理,天然Promise鏈?zhǔn)秸{(diào)用
缺點(diǎn):
- 默認(rèn)不處理404/500等錯(cuò)誤狀態(tài)碼(需手動(dòng)檢查
response.ok) - 跨域請(qǐng)求需后端配置
Access-Control-Allow-Origin - 兼容性(IE不支持,需polyfill)
三、第三方庫方案
1. Axios
核心特性
- 自動(dòng)JSON轉(zhuǎn)換
- 請(qǐng)求/響應(yīng)攔截器
- 取消請(qǐng)求(
CancelToken) - 客戶端防御XSRF
示例代碼
axios.post('https://api.example.com/submit', { name: 'Charlie' })
.then(response => console.log(response.data))
.catch(error => {
if (error.response) {
console.error('服務(wù)器錯(cuò)誤:', error.response.status);
} else {
console.error('網(wǎng)絡(luò)錯(cuò)誤:', error.message);
}
});
2. jQuery AJAX
傳統(tǒng)寫法
$.ajax({
url: 'https://api.example.com/data',
type: 'GET',
dataType: 'json',
success: function(data) { console.log(data); },
error: function(xhr, status, error) { console.error(error); }
});
簡寫形式
$.get('https://api.example.com/data', function(data) {
console.log(data);
});
四、特殊場景方案
1. 表單模擬提交(PUT/DELETE)
通過隱藏表單實(shí)現(xiàn)非GET/POST方法的提交:
function submitWithMethod(url, method, data) {
const form = document.createElement('form');
form.method = 'POST'; // 表單原生不支持PUT/DELETE
form.action = url;
// 添加_method字段模擬真實(shí)HTTP方法
const methodInput = document.createElement('input');
methodInput.type = 'hidden';
methodInput.name = '_method';
methodInput.value = method;
form.appendChild(methodInput);
// 添加數(shù)據(jù)字段
Object.entries(data).forEach(([key, value]) => {
const input = document.createElement('input');
input.type = 'hidden';
input.name = key;
input.value = value;
form.appendChild(input);
});
document.body.appendChild(form);
form.submit();
}
// 使用示例
submitWithMethod('/orders/123', 'PUT', { status: 'shipped' });
2. 文件上傳進(jìn)度監(jiān)控
const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://api.example.com/upload', true);
// 上傳進(jìn)度事件
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
const percent = Math.round((e.loaded / e.total) * 100);
console.log(`上傳進(jìn)度: ${percent}%`);
}
};
xhr.send(new FormData(document.getElementById('uploadForm')));
五、選擇建議
| 場景 | 推薦方案 | 理由 |
|---|---|---|
| 現(xiàn)代瀏覽器開發(fā) | Fetch API | 語法簡潔,支持流式處理,與Promise生態(tài)無縫集成 |
| 需要兼容IE | Axios | 自動(dòng)降級(jí)處理,提供統(tǒng)一的錯(cuò)誤處理機(jī)制 |
| 復(fù)雜業(yè)務(wù)邏輯 | Axios攔截器 | 通過攔截器統(tǒng)一處理認(rèn)證、日志、錯(cuò)誤重試等橫切關(guān)注點(diǎn) |
| 大文件上傳 | XHR | 支持進(jìn)度監(jiān)控,可配合分片上傳策略 |
| 表單重定向提交 | 隱藏表單法 | 瀏覽器自動(dòng)處理Cookie,后端可識(shí)別_method字段模擬PUT/DELETE |
六、最佳實(shí)踐
錯(cuò)誤處理:始終檢查HTTP狀態(tài)碼,不要依賴catch捕獲所有錯(cuò)誤
安全防護(hù):
- 敏感操作使用HTTPS
- 跨域請(qǐng)求配置CORS頭
- 重要操作添加CSRF Token
性能優(yōu)化:
- 合理使用緩存(
Cache-Control) - 大文件采用分片上傳
- 頻繁請(qǐng)求使用WebSocket或Server-Sent Events
調(diào)試技巧:
- 使用瀏覽器Network面板驗(yàn)證請(qǐng)求頭/體
- 通過
console.log(response)檢查原始響應(yīng)結(jié)構(gòu) - 復(fù)雜場景使用Postman等工具先驗(yàn)證接口
結(jié)語
JavaScript請(qǐng)求方案的選擇應(yīng)基于項(xiàng)目需求、團(tuán)隊(duì)熟悉度和瀏覽器兼容性?,F(xiàn)代項(xiàng)目推薦以Fetch API為主,復(fù)雜場景引入Axios增強(qiáng)功能,同時(shí)保持對(duì)XHR的理解以便維護(hù)遺留代碼。無論采用哪種方案,始終牢記安全性、可維護(hù)性和性能這三個(gè)核心原則。
到此這篇關(guān)于JavaScript發(fā)送HTTP請(qǐng)求的主要方法詳解的文章就介紹到這了,更多相關(guān)JavaScript發(fā)送HTTP請(qǐng)求內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
javascript實(shí)現(xiàn)拖拽并替換網(wǎng)頁塊元素
實(shí)現(xiàn)類似于學(xué)生換座位的效果,將網(wǎng)頁內(nèi)的兩個(gè)元素通過拖拽的方式互換。2009-11-11
純JS實(shí)現(xiàn)表單驗(yàn)證實(shí)例
這篇文章主要介紹了純JS實(shí)現(xiàn)表單驗(yàn)證實(shí)例,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-12-12
解決npm安裝Electron緩慢網(wǎng)絡(luò)超時(shí)導(dǎo)致失敗的問題
下面小編就為大家分享一篇解決npm安裝Electron緩慢網(wǎng)絡(luò)超時(shí)導(dǎo)致失敗的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-02-02
WebGL利用FBO完成立方體貼圖效果完整實(shí)例(附demo源碼下載)
這篇文章主要介紹了WebGL利用FBO完成立方體貼圖效果的方法,以完整實(shí)例形式分析了WebGL實(shí)現(xiàn)立方體貼圖的具體步驟與相關(guān)技巧,并附帶了demo源碼供讀者下載參考,需要的朋友可以參考下2016-01-01

