You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django REST API可通过Swagger POST,Postman/Vue Axios请求失败

问题排查:Vue Axios POST请求Django API返回400错误(Unsupported media type "text/plain")

我有一个Django模型,通过Admin界面或Swagger的POST请求能正常添加记录,但Vue表单用Axios请求时返回400错误且无额外提示;用Postman测试时返回错误:"detail": "Unsupported media type \"text/plain\" in request."。三种请求的JSON内容基本一致,仅Swagger的JSON带有换行符,但只有Swagger请求成功。同一Vue应用内其他表单可正常工作,现寻求排查方案。


一、请求对比信息

1. Swagger成功请求的JSON数据

{
    "matchingKey": "chgpt-a",
    "sequence": 1515,
    "param_kwargs_json": {},
    "param1": "tensorFlow",
    "param2": "N/A",
    "param3": "N/A",
    "param4": "N/A",
    "param5": "N/A",
    "param6": "N/A",
    "param7": "N/A",
    "param8": "N/A",
    "param9": "N/A",
    "param10": "N/A",
    "description": "test from postman 1331"
}

2. Swagger响应头

access-control-allow-origin: * 
 allow: GET, POST, HEAD, OPTIONS 
 content-length: 265 
 content-type: application/json 
 cross-origin-opener-policy: same-origin 
 date: Fri, 07 Apr 2023 06:27:13 GMT 
 referrer-policy: same-origin 
 server: WSGIServer/0.2 CPython/3.10.9 
 vary: Accept, Origin, Cookie 
 x-content-type-options: nosniff 
 x-frame-options: DENY

3. Postman测试的请求头

request_headers= {'Content-Length': '222', 'Content-Type': 'application/json', 'Host': 'localhost:8000', 'Connection': 'keep-alive', 'Sec-Ch-Ua': '"Google Chrome";v="111", "Not(A:Brand";v="8", "Chromium";v="111"', 'Accept': 'application/json, text/plain, */*', 'Sec-Ch-Ua-Mobile': '?0', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36', 'Sec-Ch-Ua-Platform': '"Windows"', 'Origin': 'http://localhost:444', 'Sec-Fetch-Site': 'same-site', 'Sec-Fetch-Mode': 'cors', 'Sec-Fetch-Dest': 'empty', 'Referer': 'http://localhost:444/', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'en-US,en;q=0.9'}

二、相关配置代码

1. Django CORS配置

CSRF_TRUSTED_ORIGINS = ["http://localhost:8000", "http://localhost:444/"]
#CSRF_COOKIE_DOMAIN = '.localhost'

CORS_ALLOW_ALL_ORIGINS = True

CORS_ALLOWED_ORIGINS = [
    'http://127.0.0.1:8000',
    'http://localhost:8000',
    'http://127.0.0.1:5173',
    'http://localhost:5173',
    'http://127.0.0.1:444',
    'http://localhost:444'
]

2. Vue表单提交方法

saveParameter(_newParameters){
        console.log('saveParameter()')
        this.swalLoading('Adding New Parameter...')
        //check for completeness
        if(true){
            console.log('saveParameter data = %s', _newParameters.matchingKey)
            setTimeout(()=>{
            // POST API FOR ADDING Parameter
            getAPI.post('http://localhost:8000/api/parameters/', _newParameters)
            .then(res=>{

                // SETS MESSAGE FOR RESPONSE
                let message = `Parameter ${res.data.requestpath} ${res.data.requestmethod} has been successfully added.`

                // DISPLAYS SUCCESS SCREEN/MODAL
                this.swalSuccess(message)

            })
            .catch(err=>{
                this.swalError(err)
            })
        }, 1000)
        }

三、控制台错误日志

toggleAddParameterModal
mixins.js:130 --mixins toggleModal(addParameter)
mixins.js:139 Proxy(Object) {closeModal: ƒ, …}
ParametersTableModal.vue?t=1680847383434:119 saveParameter()
ParametersTableModal.vue?t=1680847383434:123 saveParameter data = moogoogaipan
mixins.js:130 --mixins toggleModal(addParameter)
mixins.js:139 Proxy(Object) {closeModal: ƒ, …}
xhr.js:187          POST http://localhost:8000/api/parameters/ 400 (Bad Request)
dispatchXhrRequest @ xhr.js:187
xhrAdapter @ xhr.js:13
dispatchRequest @ dispatchRequest.js:53
request @ Axios.js:108
Axios.<computed> @ Axios.js:140
wrap @ bind.js:9
(anonymous) @ ParametersTableModal.vue?t=1680847383434:126
setTimeout (async)
saveParameter @ ParametersTableModal.vue?t=1680847383434:124
(anonymous) @ ParametersTableModal.vue:111
(anonymous) @ runtime-dom.esm-bundler.js:1450
callWithErrorHandling @ runtime-core.esm-bundler.js:155
callWithAsyncErrorHandling @ runtime-core.esm-bundler.js:164
invoker @ runtime-dom.esm-bundler.js:339
mixins.js:130 --mixins toggleModal(parametersTable)
mixins.js:139 Proxy(Object) {validate: ƒ, formatPrice: ƒ, formatPriceIntl: ƒ, …}

四、排查与解决建议

1. 强制设置Axios请求头

即使默认配置存在,显式指定Content-Type确保请求被正确识别:

getAPI.post('http://localhost:8000/api/parameters/', _newParameters, {
    headers: {
        'Content-Type': 'application/json'
    }
})

同时确认_newParameters是纯JavaScript对象,未被意外转为字符串。

2. 检查Django REST Framework解析器配置

确保全局或视图级配置包含JSON解析器:

REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES': [
        'rest_framework.parsers.JSONParser',
        # 保留其他需要的解析器
    ]
}

3. 处理CSRF Token

跨域请求需携带CSRF Token,在Vue中添加如下逻辑:

// 获取Cookie中的CSRF Token
function getCookie(name) {
    let cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        const cookies = document.cookie.split(';');
        for (let i = 0; i < cookies.length; i++) {
            const cookie = cookies[i].trim();
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}
const csrftoken = getCookie('csrftoken');

// 请求时添加头
getAPI.post('url', data, {
    headers: {
        'Content-Type': 'application/json',
        'X-CSRFToken': csrftoken
    }
})

4. 校验请求数据格式

确保param_kwargs_json是对象而非字符串,若来自表单输入需手动解析:

_newParameters.param_kwargs_json = JSON.parse(_newParameters.param_kwargs_json || '{}');

内容的提问来源于stack exchange,提问作者Ali Vleotsky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 15:04:57