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

