22 ms·
You don't need that CORS request
- malft 5y agoBefore you start rearchitecting your app, be sure to check if the only reason you're seeing preflights on GET is that someone added a dumb X-Requested-By header. (You can even do POSTs without preflight if you use a whitelisted content-type.)
- sedro 5y agoAre you conflating CORS with some specific product?
- ec109685 5y agoNo, referring to this: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simpl... And the case where preflight isn’t needed despite using CORS.
- smarx007 5y agoFor example, JQuery: https://stackoverflow.com/questions/3372962/can-i-remove-the-x-requested-with-header-from-ajax-requests#24719409 https://stackoverflow.com/questions/3372962/can-i-remove-the...
- miyuru 5y agoWhat is the author trying to say, it is very hard to recognize the answer of the article. Is it to point requests to sub path of the main domain to reduce OPTIONS requests? eg: api.example.com ---> example.com/api In that case why not use proper "Access-Control-Max-Age" headers? https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Ac...
- wereHamster 5y agoChrome imposes a limit of 2h on Access-Control-Max-Age (other browsers may differ). Anyway, today we have the tools to expose different backends through the same domain. Reverse proxies, k8s ingress, … a separate domain may not add much value in most situations.
- berkes 5y agoEven then, most often your backend API service runs off one domain, so it needs only one OPTION request ever two hours for the user session. If your users make only one request per two hours, that still doubles the requests, so in that case caching'll hardly help. But in more typical cases, where one session does 20+ requests, it's a meagre 5% of the requests. In which case 'resolving that n+1 request' or 'speeding up that 1200ms response' is far better low hanging fruit than removing the single OPTIONS request. It depends on your case, though.
- franga2000 5y agoSubdomains absolutely have value! It doesn't matter that we have those tools "today" (it's not like we didn't have reverse proxies many years ago), different domains are still the only way to truly split up traffic. A reverse proxy by definition doubles your total bandwidth requirement, which is expensive and inefficient if you aren't running everything in one datacenter. You'd need to not only get servers with enough bandwidth to cover their traffic, but another server with the sum of all individual server bandwidths to handle proxying. And if you want to do geographic sharing, you either need to shard all services, or be fine with an increase in latency for non-sharded services.
- todd3834 5y agoYes I believe the article is suggesting exactly that. Even with that header users will still hit that latency on the first request. If the goal is to lower latency on first page load then that won’t help. Although it should definitely help after that.
- conradfr 5y ago
- r_singh 5y agoTry doing this with Heroku and you’ll decide that you want CORS after a few hours.
- taftster 5y agoWhy?
- selfup 5y agoIf you don't have an edge proxy (additional compute) you then accept all requests, or accept that a simple header is telling the truth.
- frenchman99 5y agoYou can have 2 Heroku apps, one for frontend with little resources since it's all static and one for API with more resources. Then create a custom Nginx config on the static app to redirect API requests and it should work fine.
- r_singh 5y agoDoesn’t that create a single point of failure for both the services?
- londons_explore 5y agoFor most services, if the static server is down, the service is down as far as the user is concerned. Therefore the added dependency may not reduce end-user-percieved reliability.
- r_singh 5y agoI reckon that most software services in the world are B2B rather than B2C (guessing from the fact that most users spend most of their time on a handful of services).
- toomim 5y agoCORS is such an ugly web standard. It's not only a pain in you butt, but it also makes your requests slow through these extra pre-flight round-trips. I have hope that we can remove it, though, in new versions of HTTP. CORS only exists because XMLHTTPRequest broke the assumptions of web 1.0 servers. Suddenly any web browser loading any page anywhere could make a request to your server without the user's explicit permission, and a ton of web servers had already been built and were running under the assumption that users would only hit their endpoints by explicitly typing in a URL or clicking on a link. But each time we design a new version of HTTP, we get an opportunity to remove CORS restrictions for it, because there aren't any servers running the new version yet. And with Braid (https://braid.org https://braid.org), we're making changes that are big enough that I think it really warrants taking a fresh look at all of this stuff. So I have hope that we can eliminate CORS and all this ugliness.
- rfraile 5y agoInstead of sending a request before every defined case in the CORS policy, it could be implemented requesting only one GET to a plain file (fully cacheable) with the domain policy definition. Like robots.txt for the search engines.
- dmw_ng 5y agoThis is how Macromedia Flash handled it a lifetime ago
- moralestapia 5y agoFlash was 20 years ahead of its time (even though it already had its share of fame). Apple killed it to pave way for the App Store. It was a shame because around that time Flash was at its peak of innovation, with stuff like Alchemy (whose modern day equivalent could be WebAssembly) and Flex (no-code thingy that was TRULY catching up, only 10 years ago). It was also starting to implement features like atomics, shared data buffers, app bundles, hardware-accelerated 3D, etc... They also went to great lenghts to open their VM, and the ecosystem that was being generated around that was awesome (anyone here used haXe back then?). It was also present on like 99% of devices already and it was the only thing at the time that truly felt like "write once, run anywhere" (HTML wasn't as feature-rich and still quite fragmented between browsers). Flash was the single biggest threat to Apple's planned business model, and with it gone, Apple's road to becoming a trillion-dollar company has been a walk in the park.
- eins1234 5y agoThe author mentions Cloudflare as having the ability to rewrite requests from `api.website.com/*` to `website.com/api/*`. Is that functionality available as a page rule or would we have to use workers and pay for every request rewritten? I remember taking a look at this a while ago and only found ways to do this through workers, so was turned off by the potential cost scaling. Ended up just setting a high `Access-Control-Max-Age` and calling it a day. But maybe I've missed a more cost effective way to accomplish this?
- deleted 5y ago[deleted]
- deleted 5y ago[deleted]
- gnfargbl 5y agoI also can't find a way to do this with page or transform rules. Trying to create a rule which modifies the Host header is met with an error message. Apparently only Enterprise customers can do this [1] [2]. [1] https://support.cloudflare.com/hc/en-us/articles/206652947-Using-Page-Rules-to-Re-Write-Host-Headers https://support.cloudflare.com/hc/en-us/articles/206652947-U... [2] https://community.cloudflare.com/t/rewrite-host-header-in-page-rule/143639 https://community.cloudflare.com/t/rewrite-host-header-in-pa...
- eins1234 5y agoAh yes that has been the story of my life on Cloudflare. Anything remotely interesting is gated behind what I can only assume is a thousands of dollars per month Enterprise plan.
- geuis 5y ago> You don’t need that CORS request …if you’re using a proxy like Cloudflare. The short version of this post is that if your api is hidden behind Cloudflare, you can have it proxy requests to you api that lives on a subdomain.
- frenchman99 5y agoA reverse proxy using Nginx would work just as well.
- colinclerk 5y agoMy favorite way to avoid preflights is to have Next.js handle the reverse proxy. It fits my mental model better to have it code-side instead of putting Cloudflare/Fastly in front.
- deleted 5y ago[deleted]
- smt88 5y agoThat does avoid preflight, but it just adds additional requests for all static assets. It seems like it's just trading one type of overhead for another.
- crooked-v 5y agoI do this enough that I really had Next had some config-level handling for API reverse proxy stuff instead of writing a /api wrapper for each.
- colinclerk 5y agoCheck out “rewrites”: https://nextjs.org/docs/api-reference/next.config.js/rewrites https://nextjs.org/docs/api-reference/next.config.js/rewrite...
- avereveard 5y agoOr just declare JSON as text, simple cors supports authentication, no need to mess with routes.
- avereveard 5y ago
- nesarkvechnep 5y agoAren’t `OPTION` requests useful when you want to build an actual REST API and not what most devs call everything having an HTTP interface? The clients can use the requests to understand which actions they can apply to the resources.
- herpderperator 5y agoThe irony in this is that with CloudFront at least, it can't strip the "/api" prefix before sending it to your backend, so you have to have your backend server understand /api/xyz rather than just /xyz calls like when it was on a dedicated api subdomain. But don't worry! AWS thought of this! They invented Another Cloud Thing, namely Lambda@Edge, to solve this. Now you can run a JS function for every single request that hits your CloudFront Distribution so that you can run logic in there to strip the prefix before it gets passed to your origin. You read that right! Execute code every time a request hits your proxy! But wait, doesn't executing code for every single request sound insane AND doesn't it also add latency which this was trying to remove? Yes! Isn't cloud just lovely?
- Cthulhu_ 5y agoCloudFront is a CDN, it should cache static resources, not so much manipulate incoming requests - that's more a job for a load balancer / proxy like Elastic Load Balancer.
- youngtaff 5y agoCloudFront is CDN with limited features, other CDNs (Akamai, Fastly etc) are more than capable of manipulating incoming requests
- Tea418 5y agoFully agree here: I don’t expect anything else but reliable and performant HTTP caching from a CDN like CloudFront. Request manipulation is not the duty of a cache - even though other CDN providers mix request manipulation functionality with caching. In my opinion, they don’t need to be in the same product. If you still need request manipulation, because you don’t control the origin or you don’t want to introduce another service between CloudFront and the origin, you would use CloudFront Functions, which is cheaper than Lambda@Edge and easy to set up.
- herpderperator 5y agoCloudFront Distributions cannot pass the request to CloudFront Functions before sending to the origin. In other words, they cannot be used to modify origin request/responses. They can only modify the viewer request/responses. [0] Only Lambda@Edge can help the scenario which I provided, which is also AWS's recommended solution. [1] [0] https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cloudfront-functions.html https://docs.aws.amazon.com/AmazonCloudFront/latest/Develope... [1] https://aws.amazon.com/blogs/architecture/serving-content-using-fully-managed-reverse-proxy-architecture/ https://aws.amazon.com/blogs/architecture/serving-content-us...
- donatj 5y agoIs there any way to read the OPTIONS response from JavaScript? I'm guessing not, but if there was, theoretically could you just include your API response in the CORS rejection response?
- corentin88 5y agoNope, because OPTIONS requests have no body [1] [1] https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OP...
- londons_explore 5y agoSo can we place the whole body in a response header called X-Body:?
- corentin88 5y agoWhile it’s definitely not recommended to do so, you could probably do it. You need to test it out though, not sure every browser will support this.
- yaur 5y agoCORS exists to protect the backed from developers that ask these types of questions.
- CrimsonRain 5y agoLet's not be mean to someone asking a question. It is always good to ask, even stupid ones.
- yaur 5y agoI'm not mean to anyone with less karma than me.
- weitzj 5y agoFrom my experience, when you want to have 12 factor apps and just build your Frontend/backend once, and don’t want to leak absolute urls in the Frontend code, you are better of with relative URL’s anyways, i.e. /api for your api, and let a reverse proxy do the proper mapping to your services. Then of course you don’t need CORS
- Cthulhu_ 5y agoThat's what I tend to stick to, CORS is a headache and very easy to do wrong and you shouldn't do it unless you make an open API that can be directly integrated into other websites - which is probably a bad idea. For most if not all use cases, you can set up a proxy in your front-end's web server so that it doesn't need CORS.
- youngtaff 5y agoThis!
- 9dev 5y agoThat's one strategy. Having something like `API_URL=https://api.foo.bar/v1 https://api.foo.bar/v1` works equally well for 12 factor apps, and gives you the added benefit of transparently pointing to test hosts or staging versions running elsewhere.
- weitzj 5y agoYeah. I would have this env var inside my reverse proxy to have it 12-factor app compatible. And I guess your solution as well? And you have some templating mechanism to replace the absolute variable on the fly? I would use a mix of your solution, i.e. allow the Java script client to be configured with either absolute or relative urls in case one needs to point the client elsewhere + reverse proxy
- wdb 5y agoDidn't we do this back in the day for IE?
- ManuelKiessling 5y agoHere is an extensive step-by-step tutorial which describes in detail how to create and deploy a React-based web app frontend using TypeScript and Redux Toolkit on top of a Node.js based AWS Lambda backend with a DynamoDB database, connect and integrate them through API Gateway and CloudFront, and explains how to codify and automate the required cloud infrastructure and deployment process using Terraform. The resulting architecture does not require any CORS requests, too: https://manuel.kiessling.net/2021/05/02/tutorial-react-single-page-applications-spa-with-a-serverless-aws-api-gateway-and-lambda-and-dynamodb-backend-and-terraform-infrastructure-as-code/ https://manuel.kiessling.net/2021/05/02/tutorial-react-singl...
- hajhatten 5y agoThat's a mouthful.
- szszrk 5y agoI've read that sentence three times and still were not sure if it's meant as a joke or not.
- ManuelKiessling 5y agoIt’s not – I like to summarize my tutorials comprehensively. I am not a native speaker though; I apologize if the sentence isn’t structured correctly or sounds inelegant. Corrections welcome.
- 9dev 5y agoI guess it's just the mind-bogglingly huge number of components involved to display HTML to someone :)
- ManuelKiessling 5y agoThat is absolutely true in some sense - then again, it is one solution where you start with a decent architecture that can grow and is scalable at linear, and very low, costs. If you were to really only deliver some HTML, it's overkill. For this reason, my blog is hosted with an old-school 90s-style FTP-backed "webspace" provider. But the architecture described is used to develop-build-deploy a full-flegded web-based application, with a persistence layer for user data and a potentially complex user-interface. And for this, having a sound architecture and tech-stack where you do not need to care about low-level server issues is, while certainly not a silver bullet, quite a productive experience.
- zagrebian 5y agoLooking at some of my HTTP requests, I noticed that * `Sec-Fetch-Site: cross-site` can be `Sec-Fetch-Mode: no-cors` * `Sec-Fetch-Site: same-origin` can be `Sec-Fetch-Mode: cors` It looks like all four combinations of these two headers are possible.
- Ralo 5y agoRecently chrome required COOP and COEP for shared memory access, which essentially restricts any access to anything besides the same origin. This basically killed my project/motivation of 2~ years. Using Emscripten and threads, you require COOP & COEP headers to be sent via the main document. This is not common practice for static html hosting sites, thus requiring that you have access to a config file or .htaccess, and requires ALL assets to be hosted exclusively on that same server. Killing my project is a bit extreme, but killed my motivation. It's a web-based game with multiplayer that I was hoping people would modify and expand on, hosting themselves, uploading to places like Github. I've recently started modifying Emscripten's runtime library to try and treat each webworker as a separate instance that just communicates between each other. This has major overhead as each thread is a new memory instance. I've tried getting it to extract each function into it's own module for a webworker to load but that's a major task. Web apps want to act as desktop applications but they're so held back by security it's nearly impossible. We don't even have a proper local storage system. To quote Dilbert, "Security is more important than usability. In a perfect world, no one would be able to use anything."
- Tepix 5y agoHere's the Dilbert strip: https://dilbert.com/strip/2007-11-16 https://dilbert.com/strip/2007-11-16
- _puk 5y agoI may have misunderstood your requirements, but why do you say that most static hosts don't allow custom headers to be set? I know that Netlify does[0], and use it myself, so I would expect the other big names to support something as well. 0: https://docs.netlify.com/routing/headers/ https://docs.netlify.com/routing/headers/
- Ralo 5y agoI really wanted to give developers more control over their asset hosting. If they wanted to host their assets on a remote server for better performance, that's an option I'd want them to have. Relying on only X Y Z service will certainly work, but certainly not optimal. It didn't out right kill the project, It'll work under these specific conditions but reducing usability is not helpful.
- kzemek 5y agoOr you can have the browser cache the CORS header for up to 2 hours (cross-browser), for the same performance effect - but it will also work for third party website consumers of your API that you can't just put on your domain.
- miyuru 5y agoThe author did not actually solve the problem at hand. Try the API playground[1] on the authors site. Its takes more than 1 secs for me to get a preflight response back. The preflight request hits fastly and aws apigateway and maybe the application well. There are lot of options to solve the problem at fastly and apigateway as I mention in another comment[2]. I really hope author reads the comments here. [1] https://www.meetup.com/api/playground/ https://www.meetup.com/api/playground/ [2] https://news.ycombinator.com/item?id=29778973 https://news.ycombinator.com/item?id=29778973
- deleted 5y ago[deleted]
- cwilby 5y agoI'm not 100% on this, but doesn't disabling CORS essentially re-introduce CSRF?
- cwilby 5y agoTheory is that an attacker can bypass CSRF protections when CORS is disabled by making an extra GET request to parse the CSRF token which is then provided in the next request.
- cwilby 5y agoThen again, I suppose a dedicated attacker can just bypass CORS.
- tasn 5y agoThey are bot disabling CORS, they are just proxying the request throigh the same origin so that for their web app they won't have CORS requests.
- JimDabell 5y agoI think you misunderstand what CORS is. Are you under the impression CORS is a way of blocking requests? It’s the other way around. Browsers prevent most types of requests that go from one hostname/port/protocol to another by default. CORS is a way for a server to tell browsers to relax these restrictions in some way. If you disable CORS, all that means is that the default browser behaviour applies, which means that more types of requests are prevented.
- cwilby 5y agoThanks for helping to clarify!
- 02020202 5y ago
- zemnmez 5y agoPlease use Access-Control-Max-Age instead. CORS has some nice security properties.
- jefftk 5y agoWhat is the security risk of moving from an API subdomain to a single host?
- cerved 5y agonothing CORS is just a verification that the cross domain request is to a trusted domain. Your own domain is assumed to be trusted, by default
- jefftk 5y agoThat is also my understanding, but I'm trying to find out what my parent thinks the security advantage is
- zemnmez 5y agoCORS tries to prevent CSRF issues by preventing cross-origin cookie authentication.
- adamddev1 5y agoIs avoiding the OPTIONS request as simple as keeping a fetch to the same origin? I thought there were all kinds of rules for something to be considered a "simple request", like it can't be JSON, can't be PUT or DELETE, etc. I haven't looked much into this but does someone have a clear answer?
- jorams 5y agoThose rules[1] specify whether or not a cross-origin request is considered "simple". If the request is not cross-origin, you can basically do whatever you want. [1]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simpl...
- SergeAx 5y agoHint for those who didn't fall for cloud behemoths vendor lock. Deploying your app to plain VPS you still need a reverse proxy like nginx to handle raw requests and terminate TLS. So it is natural to let it do the routing part too.
- crazypython 5y agoGoing to implement this to improve Denigma.app load time!
- mrweasel 5y agoI've struggled with this exact problem. A client developed a SPA and an API to go with it. Because "reasons" they wanted the API to live on api.customersite.com. Fair enough, that's their problem. Except it's not, because the developers have no idea how CORS work, only that it's a thing. So their API can't send CORS headers back, they never implemented that and apparently can't figure out how to make it work. Instead, we now have a reverse proxy (haproxy) that "fixes" the missing CORS headers, by intercepting the OPTIONS call and return a dummy response with the correct headers included. The developer basically understand NOTHING in regards to CORS, so whenever the silly SPA breaks, the logic is always the same: "CORS is broken, fix it". At not point has it been an option to fix the API service to include the correct headers. We could just have moved the API to /api and saved days of debugging and writing work-arounds, but no, api.customersite.com looks more professional.
- capableweb 5y agoHow you can be a web developer today and not knowing how to add two headers to all responses a API does, boggles my mind. Literally took me about 30 minutes to understand how CORS works when it first started being shipped with browsers.
- gitgrump 5y agoYou probably understand the rest of what you need to understand CORS. I've noticed that web developers today don't even understand things like HTTP in general particularly well. They're not trying to understand, they're trying to ship the next feature, and CORS is "blocking them".
- epolanski 5y agoSadly true, I love to ask webdevs in intervews if they can give definitions of http, or idk, user agent, and it's impressive how much ignorance there is out there.
- thakoppno 5y agoIn my experience with CORS, my problem is it takes 30 minutes nearly every time you need to bugfix it. It’s not that complicated but when something breaks CORS adjacent, you’re stuck reviewing the gotchas.
- noduerme 5y agoDoes this work if you want to allow an iframe to execute code in a parent browser window from a different domain? (Assuming you control both domains and can inject a different Sec-fetch-mode header into the parent page)? Context here: I'm maintaining a PWA that has to run on local iphones/android devices and maintain contact with a server on local networks in the 127.x block. But the point of download for the app itself is under an https domain on the open internet. It uses an iframe to check lots of local 127.x.x addresses until it finds one with a local server, and bootstraps itself to the code on the local server that way; unfortunately, it can't run as a true PWA because the iframe at the center of it violates CORS (due to the ban on mixing clear and SSL requests in the more recent versions of Chrome and Safari). Would be nice if the local servers could simply serve up their content and control the window without a whole domain-specific postMessage protocol.
- JimDabell 5y agoThis approach relies on the backend proxying `/api` to the API. In other words, the client requests http://www.example.com/api/foo http://www.example.com/api/foo, then the backend goes off and fetches http://api.example.com/foo http://api.example.com/foo, then sends it back to the client. You can’t do that because in your case only the client can connect to the local networks; your backend has no access.
- noduerme 5y agoAh. ok. I didn't realize this was strictly a backend call.
- ngrilly 5y agoI don’t understand what the article is actually recommending. To avoid CORS requests, I usually proxy www.foobar.app/api to api.foobar.app, but it seems like the article is suggesting the opposite.
- jefftk 5y agoThe author is recommending that the client see only requests to foobar.app, and if you have a separate host for the API, you use a reverse proxy. Which I think is also what you are saying you do?
- ngrilly 5y agoYes, that’s what I’m usually doing.
- Traubenfuchs 5y agoYou are not the only one being confused. I think the author mixed it up?
- ngrilly 5y agoI’m under the same impression :)
- dinkleberg 5y agoThis is quite timely, was getting frustrated with some CORS issues last night because I am using the domain & api.domain schema. Will have to give this a try.
- vfistri2 5y agoimho CORS is poorly designed mechanism, you should be able to flag api.domain.com as a safe place, making a single cors request at start of user interaction with your app. Also some sort of caching should be more than welcome. On a side note at previous company I've worked at, speed was critical, so we were forced to do same tactic, use /api instead of api.domain.com which resulted in huge improvements :)
- chrisoverzero 5y ago> Also some sort of caching should be more than welcome. I have good news: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Ac...
- _xnmw 5y agoYou don't even need an SPA. Having the backend + frontend share the same state makes development so much faster and easier it's shockingly refreshing. When building a SaaS project last year I decided to just ditch React/Angular/Vue and did everything server-side like it was 2005. I was extremely pleased at the result -- everything feels snappy, secure, and native for the browser. I was shocked at how much time and headache I saved: not having to design/deploy an API and all the trimmings (ACLs, CORS, JWTs etc.), not having to spend X hours a day wrestling with Webpack/hot reloading/npm/tree-shaking/state management, having direct access to backend secrets/state/APIs and just spitting out HTML, it's just so....lovely. It simplifies performance tuning as well, the only thing I need to optimize is the server, which is easy to do because I have 100% control and visibility, compared to debugging/optimizing JavaScript for a million different clients.
- southerntofu 5y agoAnd as a bonus, your site works perfectly in degraded environments (poor network conditions, no JS runtime). It's really the best way to do things: SPAs are great for applications, but for 99% of websites server-side rendering only has advantages.
- Spivak 5y agoWait what? Other than "the client blocks JS" which is niche beyond niche the SPA is the one that actually performs better with a spotty network. Fully offline or "occasionally connected" is half the reason to use an SPA. Just as an example once downloaded FB messenger is fully functional over an unreliable network.
- marcosdumay 5y agoHum... I have never seen a SPA perform well with a spotty network. Yeah, I get what you are trying to get, that an SPA can retry failures, prioritize resources better, reload less data... They just never do that competently, as it is a shitload of work, and the "once downloaded" part is irrelevant, because people only ever load a couple of pages on most sites visits.
- three14 5y agoI was interested to note that the Dropbox API offers a hack to avoid the extra CORS request - among other details, their server accepts this: - Set the Content-Type to "text/plain; charset=dropbox-cors-hack" instead of "application/json" or "application/octet-stream". [0] ...which is allowed in a "Simple" request that doesn't require a separate round trip for OPTIONS. [0] - https://www.dropbox.com/developers/documentation/http/documentation https://www.dropbox.com/developers/documentation/http/docume...
- willseth 5y agoThis will result in fewer requests, but the author didn't provide any test results demonstrating that the server load was appreciably reduced. Since the preflight OPTIONS request will be cached, it will only occur for some fraction of the total volume of requests. Since those requests are also very low impact, I'm skeptical that this pattern will have a consequential impact for most APIs.