一文詳解如何處理axios請(qǐng)求中post請(qǐng)求的坑
一、問(wèn)題描述
- 用
axios.post()直接傳對(duì)象,后端收不到數(shù)據(jù)。 - 原因是 axios 默認(rèn)會(huì)把 POST 數(shù)據(jù)序列化為 JSON 格式,而很多后端(尤其是老項(xiàng)目)默認(rèn)只識(shí)別
application/x-www-form-urlencoded格式(即表單格式)。 - 所以數(shù)據(jù)被 “攔截” 了,本質(zhì)是前后端數(shù)據(jù)格式不兼容,而不是 axios 主動(dòng)攔截
二、代碼示例:為什么直接傳對(duì)象不行?
- 錯(cuò)誤寫法(后端收不到數(shù)據(jù))
// 錯(cuò)誤示例:直接傳對(duì)象
axios.post('/api/login', {
username: 'admin',
password: '123456' }).then(res => {
console.log(res)
}).catch(err => {
console.error(err)
})問(wèn)題分析
- axios 默認(rèn)設(shè)置
Content-Type: application/json,發(fā)送的是 JSON 字符串:
{ "username": "admin", "password": "123456" }- 如果后端是用 PHP、Java 等傳統(tǒng)方式讀取
$_POST或request.getParameter(),它們默認(rèn)只解析application/x-www-form-urlencoded格式,所以讀不到 JSON 里的字段,表現(xiàn)為 “數(shù)據(jù)傳不過(guò)去”。
三、正確的解決方案(代碼實(shí)現(xiàn))
方案一:使用 qs 庫(kù),將數(shù)據(jù)轉(zhuǎn)為表單格式(推薦)
這是最穩(wěn)妥的方式,和后端傳統(tǒng)表單提交格式完全一致。
- 安裝 qs
npm install qs --save
- 封裝請(qǐng)求(推薦寫法)
import axios from 'axios'
import qs from 'qs'
// 創(chuàng)建實(shí)例
const request = axios.create({
baseURL: '/api',
timeout: 5000
})
// 請(qǐng)求攔截器:統(tǒng)一處理 POST 數(shù)據(jù)格式
request.interceptors.request.use(config => {
// 只對(duì) POST 請(qǐng)求做處理
if (config.method === 'post' && config.data) {
// 將 JSON 對(duì)象轉(zhuǎn)為 application/x-www-form-urlencoded 格式
config.data = qs.stringify(config.data)
// 同時(shí)修改 Content-Type 頭(有些后端需要明確指定)
config.headers['Content-Type'] = 'application/x-www-form- urlencoded'
}
return config
}, error => {
return Promise.reject(error)
})
// 使用
request.post('/login', {
username: 'admin',
password: '123456'
})發(fā)送的數(shù)據(jù)格式:
username=admin&password=123456
后端可以直接用 $_POST['username'] 或request.getParameter("username") 讀取。
方案二:手動(dòng)設(shè)置 FormData(適合上傳文件或混合數(shù)據(jù))
const formData = new FormData()
formData.append('username', 'admin')
formData.append('password', '123456')
axios.post('/api/login', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})適用場(chǎng)景
- 需要上傳文件(
File對(duì)象) - 混合文本和文件數(shù)據(jù)
方案三:讓后端支持 JSON 格式(現(xiàn)代項(xiàng)目首選)
如果后端是 Node.js(Express),可以直接用中間件解析 JSON:
// 后端 Express 示例
const express = require('express')
const app = express()
// 解析 JSON 格式的請(qǐng)求體
app.use(express.json())
// 現(xiàn)在就能直接讀取 req.body.username 了
app.post('/api/login', (req, res) => {
const { username, password } = req.body
res.send({ username, password })
})前端代碼就可以保持最簡(jiǎn)潔的寫法:
axios.post('/api/login', {
username: 'admin',
password: '123456'
})四、總結(jié):為什么說(shuō) “axios 有攔截功能”?
這句話其實(shí)是對(duì) “默認(rèn)行為” 的誤解:
- axios 并沒(méi)有主動(dòng) “攔截” 你的數(shù)據(jù),而是自動(dòng)做了序列化:
- GET 請(qǐng)求:自動(dòng)把參數(shù)拼到 URL 上。
- POST 請(qǐng)求:默認(rèn)把對(duì)象轉(zhuǎn)為 JSON,并設(shè)置
Content-Type: application/json。
- 當(dāng)后端不支持這種格式時(shí),數(shù)據(jù)就 “傳不過(guò)去”,看起來(lái)像是被攔截了。
最佳實(shí)踐:
- 新項(xiàng)目:前后端統(tǒng)一使用 JSON 格式,后端配置
express.json()等中間件。 - 老項(xiàng)目:用
qs統(tǒng)一轉(zhuǎn)為表單格式,避免逐個(gè)接口處理。
到此這篇關(guān)于如何處理axios請(qǐng)求中post請(qǐng)求的文章就介紹到這了,更多相關(guān)axios中post請(qǐng)求的坑內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
原生js實(shí)現(xiàn)Flappy Bird小游戲
這篇文章主要為大家詳細(xì)介紹了原生js實(shí)現(xiàn)Flappy Bird小游戲,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12
微信小程序?qū)崿F(xiàn)全局狀態(tài)管理的方法整理
已知微信小程序中如果要做到全局狀態(tài)共享,常用的有四種方式,分別是globalData、本地緩存、mobx-miniprogram和westore,本文將帶大家看看mobx-miniprogram是如何實(shí)現(xiàn)的小程序的全局狀態(tài)管理,需要的可以收藏一下2023-06-06
利用js查找數(shù)組中指定元素并返回該元素的所有索引示例
在js數(shù)組中查找特定的元素相信對(duì)大家來(lái)說(shuō)再熟悉不過(guò)了,但越簡(jiǎn)單的東西越可能出錯(cuò),小編最近就犯了這樣的錯(cuò)誤,所以想著干脆將實(shí)現(xiàn)的代碼整理下來(lái),方便自己以后需要的時(shí)候,或者有需要的朋友們參考學(xué)習(xí),下面來(lái)一起看看吧。2017-03-03
js 用于檢測(cè)類數(shù)組對(duì)象的函數(shù)方法
下面小編就為大家?guī)?lái)一篇js 用于檢測(cè)類數(shù)組對(duì)象的函數(shù)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-05-05

