Stop sending preflight requests from axios.post
Solution 1
I found the solution for my query. As I mentioned above, our browser sends preflight request (means options request) before any other request if our request is not simple (here simple means: if request contains content-type : application/json or custom headers etc) and if we are sending this request to some other domain/ URL.
And our axios.post method carries content-type as application/json by default, that's why, my browser was sending multiple requests (means preflight request before any other request).
Now, I have changed my request content-type to application/x-www-form-urlencoded by sending data as params, as shown below:
var params = new URLSearchParams();
params.append('username', values.email);
params.append('password', values.password);
const response = await axios.post(ps.user_ms_url+ps.user_login,
params);
And handling this request at backend using @ModelAttribute annotation (Spring-boot). So, keeping request simple can stop preflight requests.
Solution 2
You can avoid CORS preflight request by proxying the request. Add this in your webpack development config
devServer: {
port: process.env.PORT || 3000,
proxy: {
'/api': {
target: 'http:localhost:8080',
pathRewrite: { '^/api': '' },
changeOrigin: true,
},
},
}
This means your request to /api/users
will forwarded to http://localhost:8080/users
.
If you are using create-react-app. just add "proxy": "http://localhost:8080"
to your package.json. Check more info here
Balram Chauhan
Updated on June 04, 2022Comments
-
Balram Chauhan almost 2 years
I have my micro-service developed using spring-boot and spring security and frontend is designed on react-hooks. Now, while I am send some data to my micro-service using axios.post method, it send CORS preflight method i.e. options method because axios by default send content-type as application/json and application.json leads to send options request to server before any other request.
I have tried sending my request with different headers and content types as 'application/x-www-form-urlencoded' also I have used @cross-origin(*) at my server end.
const config = { headers: { 'Content-Type': 'application/json' } } const response = await axios.post(ps.user_ms_url+ps.user_login, { username:values.email, password:values.password // headers:{'tokenvalue':'token'} }, config);
I expect my browser to send only post request to the server, for that I am ready to change my headers as well. Any help will be appreciated. Thanks in advance!
-
Jasper Bernales over 4 yearsThis is expected to happen if you are requesting from different domain. Are you using create-react-app for your react app? there's a way to get a way with CORS using proxy and builtin create-react-app
-
-
Balram Chauhan over 4 yearsThank you for your prompt reply. And you are right as I am requesting from different domain but I didn't understand your answer. Like, how i will be able to stop preflight methods by proxing the request as I am already able to hit the URL.
-
Balram Chauhan over 4 yearsYes, I have already provided access to * at my server end as I have provided: @CrossOrigin("*") annotation at my URL mapping which allows all the request domains to hit URL
-
Jasper Bernales over 4 yearsare you using webpack?
-
Balram Chauhan over 4 yearsno, I'm not using webpack but yes, I m using create-react-app for my react app
-
Jasper Bernales over 4 yearsas i said add this to your package.json
"proxy": "http://localhost:8080"
then add '/api' prefix to your requests to backend -
Balram Chauhan over 4 yearsI applied proxy in my package.json but it didn't work for me. And can you please tell how will it work to stop options request?
-
Jasper Bernales over 4 yearsas I said add prefix '/api' to your requests. so instead of
http://localhost:8080/login
(i dont know what the value of thisps.user_ms_url+ps.user_login
) you replace the url with/api/login
this means that your webpack-dev-server is proxying the request to your backend -
Balram Chauhan over 4 yearsI understand that but as in my case I am runnning my front end at localhost:3000 and backend at localhost:8090/someurl/someotherurl/login.... So, as per your solution, I should add a line "proxy": "localhost:8090" in my package.json and I will hit url with "/someurl/sopmeotherurl/login".... Am I right?
-
Jasper Bernales over 4 yearshere it is step by step. 1) add this to package.json
"proxy": "http://localhost:8090
. 2) repalce this/someurl/sopmeotherurl/login
with this/api/someurl/sopmeotherurl/login
-
Balram Chauhan over 4 yearsYes, I have applied exact code as you said but now it is hitting the URL as localhost:3000/api/someurl/sopmeotherurl/login
-
Jasper Bernales over 4 yearsyes that's actually what we want. webpack-dev-server should proxy your request to your backend. check your backend logs if it hits your server. what is actually the route for the login in your backend?
-
Balram Chauhan over 4 yearsNo, It is enable to hit my backend server and Route to my backend login service is : localhost:8090/someurl/someotherurl/login and what exactly my browser hitting is: http:/localhost:3000/api/someurl/someotherurl/login
-
Balram Chauhan over 4 yearscorrection- not able* (it is not able to hit server)
-
Jasper Bernales over 4 yearsI see my mistake. please take a look at this sandbox.
https://codesandbox.io/s/ecstatic-sutherland-o7gql
There's a file setupProxy.js copy it under your src and edit the target. it should work if you are using [email protected] or higher -
Balram Chauhan over 4 yearsI did as you said and your proxy is working properly. Now, my browser is hitting localhost:3000 instead of server address which is localhost:8090 and I am able to login successfully. That's good, proxying is implemented as you said but still my browser is sending 3 requests on login click, it is sending preflight request as well. And I am looking for solution to avoid multiple requests on single click and one more thing when I enter right credentials then it sends only 1 request and if I enter wrong credentials it sends 3 requests including preflight request...
-
Jasper Bernales over 4 yearsyou should use /api/ prefix on all your request. i don't think the request with preflight is proxied.
-
Jasper Bernales over 4 yearslet me know if it works and please accept my answer. thanks!
-
Balram Chauhan over 4 yearsyour proxy is implemented successfully but it is not able to stop preflight requests as I said in my question. I don't want proxified requests if it is sending OPTIONS request before POST request.