3

I have a React application based on Typescript which is hosted on my PC. I use Spring gateway to forward requests to another microservice. GET requests are working fine but for POST requests I get:

Access to XMLHttpRequest at 'http://1.1.1.1:8080/api/support/tickets/create' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

I'm hitting this Spring Cloud Gateway issue: https://github.com/spring-cloud/spring-cloud-gateway/issues/229

React code:

export async function getTicket(id: string) {
  return await axios.get(`${baseUrl}/support/tickets/ticket/${id}`);
}

export async function postTicket(
    data: TicketFullDTO
): Promise<AxiosResponse<TicketFullDTO>> {
  return await axios.post<TicketFullDTO>(
      `${baseUrl}/support/tickets/create`, data);
}

Do you know how I can disable OPTIONS request before POST and DELETE requests?

Peter Penzov
  • 1,126
  • 134
  • 430
  • 808
  • 1
    https://stackoverflow.com/questions/61189793/spring-gateway-request-blocked-by-cors-no-acces0control-allow-orgin-header – hoangdv Jan 09 '22 at 02:13
  • 3
    This has nothing to do with react, you need to respond to OPTIONS requests properly, which is a server side issue. Maybe this helps, idk. https://stackoverflow.com/questions/33331042/how-to-handle-http-options-requests-in-spring-boot – inf3rno Jan 09 '22 at 02:13
  • Another issue here is "No 'Access-Control-Allow-Origin' header ", which you should set on server side. If your API is not publicly accessible from other sites, then you should allow very specific origins, like www.myapi.com instead of using *. – inf3rno Jan 09 '22 at 02:15

3 Answers3

1
  • From server, you can return if req.method==="OPTIOINS" inside POST rotues

  • OPTIONS request is automatically sent becase because axios sets custom HTTP headers 'application/json'. With 'application/xml' or 'application/json' headers "OPTIONSare automatically sent. try to set header likeapplication/x-www-form-urlencodedin yourPOSTorDELETE` request

  • Or you can set up proxy from client.

If you are using create-react-app, in src folder create setupProxy.js

 npm install http-proxy-middleware --save

http-proxy-middleware has tons of options

then in setupProxy.js

const { createProxyMiddleware } = require('http-proxy-middleware');


module.exports = function(app) {
  app.use(
    '/api',
    createProxyMiddleware({
      target: 'http://localhost:3080',
      changeOrigin: true,
    })
  );
};

If you are using webpack, https://webpack.js.org/configuration/dev-server/

devServer: {
   historyApiFallBack: true,
   contentBase: path.resolve(__dirname, 'public'),
   proxy: {
      '/v1/**': {
         target: 'http://url',
         secure: false,
         changeOrigin: true
      }
   }
},
Yilmaz
  • 35,338
  • 10
  • 157
  • 202
0

OPTIONS pre-flight request is related to CORS policy and it is sent by the Browser automatically, so you can not disable it.

If you have access to the Server code, you can add Access-Control-Allow-Origin: YOUR_DOMAIN header in the response message.

You can check here how to configure CORS in Spring Cloud Gateway.

NeNaD
  • 18,172
  • 8
  • 47
  • 89
  • any idea how to add this in Spring Cloud Gateway configuration? – Peter Penzov Jan 09 '22 at 02:08
  • Don't use origin `*`, use the specific domain – Bergi Jan 09 '22 at 02:11
  • 1
    I updated the answer with the link to the docs for configuring CORS. Can you check it? @PeterPenzov – NeNaD Jan 09 '22 at 02:13
  • You are right. I updated my answer. @Bergi – NeNaD Jan 09 '22 at 02:13
  • I tried this: `cloud: gateway: globalcors: cors-configurations: '[/**]': allowedOrigins: "http://localhost:3000" allowedMethods: - GET` But again it's not working – Peter Penzov Jan 09 '22 at 02:33
  • But that enables only GET request. You said that you are doing POST and DELETE requests. Try adding these as well. – NeNaD Jan 09 '22 at 02:35
  • I tried this: `spring: cloud: gateway: globalcors: cors-configurations: '[/**]': allowedOrigins: "http://localhost:3000" allowedMethods: - GET - POST - DELETE - OPTIONS` Now data is not transferred for some reason – Peter Penzov Jan 09 '22 at 02:38
0

If you plan to host the react app and the backend on the same url/port and you only have this issue in development you can set up the local development server to proxy all requests to your backend.

In the package.json file, add:

"proxy": "your-backend-base-url"

You should then execute the backend calls using a relative URL.

Mordechai
  • 15,437
  • 2
  • 41
  • 82