Axios POST 请求不起作用

IT技术 reactjs api http-post axios lumen
2021-04-29 20:37:08

我知道有很多关于同样问题的问题,但没有一个解决方案对我有用。

我有一个使用 Lumen 内置 API 的 ReactJS 应用程序。该 API 也被React NativeJQuery AJAX 使用,并且在两者上都可以正常工作。

当我尝试从 ReactJS 发送带有 axiosPOST请求时,我在OPTIONS请求中收到 405 Method Not Allowed 错误

响应头 请求头

axios 请求是:

const body = { username, password };

axios.post(`{$uri}/payment/api/login`, {body})
     .then(res => console.log(res))
     .catch(err => console.log('Login: ', err));

起初我认为这是一个 CORS 问题,这会很奇怪,因为我的 API 被托管在 AWS S3 上的静态站点使用,没有任何问题。所以我的 CORS 中间件工作正常。

比我尝试使用 fetchAPI 来调用 API 并且工作正常。我尝试从 axios向虚拟 API https://jsonplaceholder.typicode.com/users发送POST请求,并且工作正常。

编辑

好的,所以我刚刚发现 fetchAPI 以application/x-www-form-urlencoded格式发送数据,该格式不受飞行前请求的影响。这应该意味着 CORS 中间件存在问题。

CORSM中间件

<?php

namespace App\Http\Middleware;

use Closure;

class CORSMiddleware
{
  /**
   * Handle an incoming request.
   *
   * @param  \Illuminate\Http\Request  $request
   * @param  \Closure  $next
   * @return mixed
   */

   public function handle($request, Closure $next)
   {
      $response = $next($request);
      $response->header('Access-Control-Allow-Methods', 'HEAD, GET, POST, PUT, PATCH, DELETE, OPTIONS');
      $response->header('Access-Control-Allow-Headers', $request->header('Access-Control-Request-Headers'));
      $response->header('Access-Control-Allow-Origin', '*');
   }
}

Lumen 中的另一个 API 构建中也使用了完全相同的中间件,并由使用axios 的Vue 前端使用

附加信息

控制台错误

GET请求在我的 API 上运行良好。

4个回答

问题很可能出在您的请求标头上。尝试至少设置 Content-Type。

let axiosConfig = {
  headers: {
      'Content-Type': 'application/json;charset=UTF-8',
      "Access-Control-Allow-Origin": "*",
  }
};
const body = { username, password };

axios.post(`{$uri}/payment/api/login`, body, axiosConfig)
 .then(res => console.log(res))
 .catch(err => console.log('Login: ', err));

或者application/x-www-form-urlencoded如果您希望在服务器端使用 url 编码数据,则将Content-Type 设置为

我遇到了这个问题,最终学到的关于 COR 的知识比我想知道的要多。最终,我从头开始,使用我能找到的所有 COR 开关重新创建 API,然后将代码剥离为:

axios.post(postUrl).then(
  (res) => {
    console.log('Axios:',res);
    console.log('Axios data:',res.data);
  }).catch((err) => { console.log('Axios Error:', err); })

像魅力一样工作。标头是必需的服务器端,而不是我的应用程序。我希望这对你有帮助。

在您的请求之前使用 OPTIONS 请求,以检查是否允许您执行来自该域的请求以及可以使用哪些标头。

此 OPTIONS 请求失败,因为数据和 Content-Type 冲突。

您需要在您的请求中添加此标头:{ 'Content-Type': 'application/json' },并使用该JSON.stringify函数来转换您的数据:

const data = JSON.stringify({ email, password });
const options = {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  data,
  url,
};
axios(options);

或者,你可以只添加你的要求这个头:{ 'Content-Type': 'application/x-www-form-urlencoded' }

const data = { email, password };
const options = {
  method: 'POST',
  headers: { 'content-type': 'application/x-www-form-urlencoded' },
  data,
  url,
};
axios(options);

解决方案取决于您的后端 API 规范。

对我来说,问题出在服务器端(Node.js)。

在应用 CORS 设置之前,我正在应用我的中间件功能(检查令牌是否存在),这导致仅发生 OPTIONS 调用。

例如

  1. app.use(verifyToken);
  2. 需要(“./startup/cors”)(应用程序)

我颠倒了他们的顺序,对我来说效果很好。