2

My web page, which is served from foo.com, makes API ajax calls to api.foo.com. As a consequence, the browsers issue a CORS OPTIONS pre-flight request before the actual API.

The problem is that there are many API calls and the time is starting to add up. Is there a method to only issue a single OPTIONS request instead of one for each API call?

I thought that adding <link rel="preconnect" href="https://api.foo.com/" crossorigin /> would to the trick, but there is still an OPTIONS request before each API call.

So, is there anyway to limit CORS requests to a single time?

AngryHacker
  • 54,471
  • 90
  • 289
  • 523
  • Don't think so. Maybe batch up requests? Or use simple requests? You can also try changing [`document.domain`](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy) - not sure it it's possible in your case though – TheMaster Feb 23 '20 at 06:06
  • 2
    This might help you https://stackoverflow.com/questions/31517737/one-options-for-all-post-requests I checked this with express.js and if you send `Access-Control-Max-Age` for `OPTIONS` *(`maxAge: 99999` in `cors` package)* then after refresh OPTIONS will gone, but this not the case for the first requests, when there is nothing to cache – artanik Feb 23 '20 at 09:37
  • Something like https://codesandbox.io/s/wandering-hooks-nriev (backend) and https://codesandbox.io/s/fancy-hill-8qnpd (frontend) – artanik Feb 23 '20 at 09:49
  • @artanik So the approach of `Access-Control-Max-Age` works and it doesn't. If you have 10 API requests on the page, on the first page load, it will issue 10 OPTIONS requests regardless if the first one returned a `Access-Control-Max-Age` value. However, on the 2nd page load, it will no longer send OPTIONS requests. – AngryHacker Feb 24 '20 at 23:47
  • Yes, exactly. This works only after reload. – artanik Feb 25 '20 at 07:16
  • Or you can make the first request, wait until finish and then make a bunch of other, these requests will be cached and `OPTION` part will be skipped. I updated the demo *(with setTimeout because I'm lazy)* and it works. – artanik Feb 25 '20 at 07:26
  • @artanik Thank you . Does the OPTIONS max age work on the domain portion of the URL or the entire URL? In other words, is setting MaxAge for call to api.foo.com/rule/1 will take care of other calls to api.foo.com like api.foo.com/other/api/123? – AngryHacker Feb 25 '20 at 07:44
  • Unfortunately, this works only for an exact path, not for a domain, because it's CORS restriction. – artanik Feb 25 '20 at 07:44
  • @artanik That's unfortunate. What if the calls are POSTs (and using exact same URL), but the body of the call varies. Does it work then? – AngryHacker Feb 25 '20 at 07:48
  • Yes, the `body` does not affect the cache and everything works as expected. In my demo body always different. – artanik Feb 25 '20 at 07:50
  • 1
    Looks like relevant https://stackoverflow.com/questions/12013216/how-to-apply-cors-preflight-cache-to-an-entire-domain – artanik Feb 25 '20 at 07:52
  • @artanik Ok, thank you. I think I got my path forward. – AngryHacker Feb 25 '20 at 08:12

0 Answers0