Reputation: 757
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.
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
GET Request works fine on my API.
Upvotes: 5
Views: 66227
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
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.
I reversed their order and it worked fine for me.
Upvotes: 0
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
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
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