Axios POST 有效,但 axios.create POST 生成 400 Bad Request Error

Posted

技术标签:

【中文标题】Axios POST 有效,但 axios.create POST 生成 400 Bad Request Error【英文标题】:Axios POST works but axios.create POST generate 400 Bad Request Error 【发布时间】:2020-04-17 07:39:20 【问题描述】:

前端框架:React JS

后端框架:Python Flask

之前,我在 package.json "proxy": "https://www.thehostofmyapi.com:6444" 中使用代理(因为我通过 SSH 连接到我工作的远程服务器)并且我在没有 axios 实例的情况下进行调用,见下文:

import axios from 'axios';

axios.post('/api/checks', foo: 'bar')
  .then(response => console.log(response));
  .catch(err => console.error(err));

一切正常,我正在发布/获取我的数据。

现在,我创建了一个 axios 实例:

const axiosInstance = axios.create(
  baseURL: '/api',
  headers: 
    'Content-Type': 'application/json',
  ,

  transformRequest: [data => keysToCase(data, snakeCase)],
  responseEncoding: 'utf8',

  validateStatus: status => status === 200 || status === 201,
);

当我发出 GET 请求时一切正常,但当我发出 POST 时,我收到 400 Bad Request Error。

下面是我在浏览器中得到的响应

data: "<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">↵<title>400 Bad Request</title>↵<h1>Bad Request</h1>↵<p>The browser (or proxy) sent a request that this server could not understand.</p>↵"
status: 400
statusText: "Bad Request"

headers:
  access-control-allow-origin: "https://www.thehostofmyapi.com:6444"
  connection: "close"
  content-length: "192"
  content-type: "text/html"
  date: "Fri, 27 Dec 2019 09:20:52 GMT"
  server: "Werkzeug/0.16.0 Python/3.6.9"
  vary: "Origin, Accept-Encoding"
  x-powered-by: "Express"

config:
  url: "/api/checks"
  method: "post"
  data: mission_id: "5df27777c85c4b639d4862ca"
  headers:
  Accept: "application/json, text/plain, */*"
  Content-Type: "application/json"

transformRequest: [ƒ]
transformResponse: [ƒ]
timeout: 0
adapter: ƒ xhrAdapter(config)
xsrfCookieName: "XSRF-TOKEN"
xsrfHeaderName: "X-XSRF-TOKEN"
maxContentLength: -1
validateStatus: status => status === 200 || status === 201

request: XMLHttpRequest
onreadystatechange: ƒ handleLoad()
readyState: 4
timeout: 0
withCredentials: false
upload: XMLHttpRequestUpload onloadstart: null, onprogress: null, onabort: null, onerror: null, onload: null, …
responseURL: "http://localhost:3000/api/checks"
status: 400
statusText: "Bad Request"
responseType: ""
response: "<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">↵<title>400 Bad Request</title>↵<h1>Bad Request</h1>↵<p>The browser (or proxy) sent a request that this server could not understand.</p>↵"
responseText: "<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">↵<title>400 Bad Request</title>↵<h1>Bad Request</h1>↵<p>The browser (or proxy) sent a request that this server could not understand.</p>↵"
responseXML: null
onloadstart: null
onprogress: null
onabort: ƒ handleAbort()
onerror: ƒ handleError()
onload: null
ontimeout: ƒ handleTimeout()
onloadend: null

两个明显的行为:

    当我将baseURL: 'https://www.thehostofmyapi.com/api' 放入axios.create 并删除package.json 中的代理时:

我得到一个 400 但注意到一个 OPTION 请求出现在服务器的日志中

    当我将代理保存在 package.json 中并放入 baseURL: '/api'

我仍然收到 400,但注意到服务器日志中没有 OPTION 请求

我听说过预检请求(显然是 OPTION 调用),但是当我不使用 axios.create 时,为什么一切正常?我该如何解决这个问题?

【问题讨论】:

这不是显示错误的方式.then(err =&gt; console.error(err));这是方式.catch(err =&gt; console.log(err)); 我知道,只是一个错字。对此感到抱歉 当你收到错误请求(状态 400)错误时,python 后端是否有任何堆栈跟踪,你能分享一下吗? 我只有INFO:werkzeug:10.138.7.214 - - [27/Dec/2019 09:29:37] "POST /checks HTTP/1.1" 400 - 【参考方案1】:

我设法解决了这个问题。我刚刚摆脱了transformRequest 并将其功能传递给axiosInstance.interceptors.request

const axiosInstance = axios.create(
  baseURL: '/api',
  headers: 
    'Content-Type': 'application/json',
  ,

  responseEncoding: 'utf8',

  validateStatus: status => status === 200 || status === 201,
);

axiosInstance.interceptors.request.use(
  config => (
    ...config,
    data: keysToCase(config.data, snakeCase),
  ),
  error => error,
);

【讨论】:

以上是关于Axios POST 有效,但 axios.create POST 生成 400 Bad Request Error的主要内容,如果未能解决你的问题,请参考以下文章

尽管在 header 中设置了有效的 JWT,但来自 axios 的 Post Request 总是返回 Unauthorized / Axios Deletes Headers

react-hook-form axios post - 无法创建有效负载

Axios POST 请求 413(有效负载太大)

axios post 请求挂在有效请求上

Axios POST 调用不适用于 JWT 令牌,而 GET 调用有效

使用带有参数对象的 Axios Post 没有返回数据