Avoiding pre-flight OPTIONS calls on CORS requests

Image for post
Image for post
A typical web application architecture

Above we have the typical way web apps are architected today.
The backend is run on an entirely different machine and its API is exposed for the world.

On another machine we have our SPA application being served up by express whose environment is built using webpack/browserify.

Because of this architecture, we end up having to make CORS requests to our own backend.

If you do a bit of reading about CORS requests on Mozilla Developer Network, you’ll find out that pre-flight OPTIONS calls are sent for all GET/POST unless they are classified as simple requests.

Image for post
Image for post
Pre-flight OPTIONS call

Criteria to be considered a simple request :

> If the request uses methods

> Allowed headers

> If the Content-Type header has a value

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

It goes without saying that those are some tight restrictions to be considered a simple request. In todays web apps, where most of us use Authorization headers, most requests (even GETs) will NOT be considered simple and hence a pre-flight call will be sent to the domain from the browser.

This is a huge blow and plays a big part in latency. Initially, I went down the path of messing about with headers to cut down the number of non-simple requests but soon realized that was a huge waste of time and code.

The right thing to do would be to route the requests to your App server(the one which serves up your built app and assets) which forwards it to the backend. And because the forwarded call is from server to server and not browser to server, we successfully avoid ALL pre-flight CORS requests!

I achieved this by choosing a decent enough open sourced library for proxy middleware: http-proxy-middleware.

Braver souls might go down the path of whipping up their own proxy concoction.

Steps to route your calls to the backend through your app server:

> Install http-proxy-middleware.

> Go to your server.js or similarly named file which whips up the express server and tell it to use the proxy middleware.

So a call that was previously api.example.com/posts/post_id would become app.example.com/api/posts/post_id, which would then be forwarded to the backend route anyways.

> Construct headers for your proxy calls.

This needs to be sent as a param to whichever library you are using to make GET/POST/PUT/DELETE calls.

Below is an example GET call using the axios library.

> And finally, don’t forget to tell your module builder about the new proxy middleware that you’re using (code below is for webpack production config).

And that is all! Enjoy avoiding those nasty OPTIONS calls using the above option :)

Written by

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store