Axios POST请求不起作用

时间:2018-07-17 10:41:11

标签: reactjs api http-post axios lumen

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

我有一个ReactJS应用程序,它使用了Lumen内置的API。该API也被 React Native JQuery AJAX 使用,并且在这两者上都能正常工作。

当我尝试从ReactJS发送带有axios的 POST 请求时,我在 OPTIONS 请求上收到405 Method Not Allowed错误。

Response Headers Request Headers

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中间件存在问题。

CORSMiddleware

<?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前端使用。

其他信息

Console Error

GET 请求在我的API上运行正常。

5 个答案:

答案 0 :(得分:1)

问题很可能与您的请求标头有关。尝试至少设置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));

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

答案 1 :(得分:0)

我遇到了这个问题,最终学习了比我想了解的更多的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); })

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

答案 2 :(得分:0)

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

此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规范。

答案 3 :(得分:0)

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

在应用CORS设置之前,我正在应用中间件功能(该功能检查令牌是否存在),这导致只进行OPTIONS调用。

例如

  1. app.use(verifyToken);
  2. require(“ ./ startup / cors”)(app)

我撤消了他们的订单,对我来说很好。

答案 4 :(得分:0)

如果您在幼虫处使用此请求,则需要从fromData中删除_method

const formData = new FormData(document.querySelector('form'));
formData.delete('_method');