Haseeb Burki
Haseeb Burki

Reputation: 757

Axios POST request not working

I know there are lots of question out there with the same issue, but none of the solutions have worked for me yet.

I have a ReactJS application consuming an API built in Lumen. The API is also consumed by React Native and JQuery AJAX and works fine on both.

When I try to send a POST request with axios from ReactJS, I get a 405 Method Not Allowed error on the OPTIONS Request.

Response Headers Request Headers

The axios request is:

const body = { username, password };

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

At first I thought this was a CORS issue, which would have been strange because my API is being consumed by a static site hosted on AWS S3 with no problems. So my CORS middleware works fine.

Than I tried using fetchAPI to call the API and that works fine. I tried to send a POST request to a dummy API https://jsonplaceholder.typicode.com/users from axios and it worked fine.

Edit

Okay so I just found out that fetchAPI sends data in application/x-www-form-urlencoded format which somehow is not subject to pre-flight requests. That should mean that there is an issue with the CORS Middleware.

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', '*');
   }
}

The exact same Middleware is also used in another API build in Lumen and consumed by Vue Front-End which uses axios.

Additional Info

Console Error

GET Request works fine on my API.

Upvotes: 5

Views: 66227

Answers (5)

Mahbubur Rahman
Mahbubur Rahman

Reputation: 109

if you are using this request at larval then you need to remove _method from fromData

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

Upvotes: 0

Prateek Jha
Prateek Jha

Reputation: 1

For me, the issue was on the server side(Node.js).

I was applying my middle-ware function (which checks whether token is present or not) before applying CORS settings, which led to just OPTIONS calls taking place.

e.g.

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

I reversed their order and it worked fine for me.

Upvotes: 0

Dyarlen Iber
Dyarlen Iber

Reputation: 103

An OPTIONS request is used before your requests in order to check if you are allowed to perform the request from that domain and what headers can be used. See.

This OPTIONS request is failing because the data and Content-Type are conflicting.

You need to add this header in your request: { 'Content-Type': 'application/json' }, and use the JSON.stringify function to convert your data:

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

Or, you can just add this header in your request: { '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);

The solution depends on your backend API specification.

Upvotes: 0

David White
David White

Reputation: 656

I had this problem and ended up learning more than I wanted to know about CORs. Eventually I started from scratch, recreated the API with all the switches for CORs on I could find and then stripped back the code to this:

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

Worked like a charm. Headers are required server side, not on my app. I hope that helps you.

Upvotes: 1

waleed ali
waleed ali

Reputation: 1195

Problem is most likely with your request headers. try setting Content-Type atleast.

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));

or set the Content-Type to application/x-www-form-urlencoded if you are expecting url encoded data in the server side

Upvotes: 6

Related Questions