54

I just learned about the Access-Control-Allow-Methods header, e.g.

Access-Control-Allow-Methods: OPTIONS, HEAD, GET

I have never used this header (just Access-Control-Allow-Origin), but I have gotten CORS to work in the past.

Is the default to allow all methods, or have I gotten lucky with undefined behavior?

Jim Aho
  • 9,932
  • 15
  • 56
  • 87
Paul Draper
  • 78,542
  • 46
  • 206
  • 285
  • This seem like a very good thing to do to let the _browser_ stop unneccesary requests from ever bothering your webserver. – Jim Aho Mar 02 '18 at 09:13

2 Answers2

52

The Access-Control-Allow-Methods header indicates which HTTP methods are allowed on a particular endpoint for cross-origin requests. If you allow all HTTP methods, then its ok to set the value to something like Access-Control-Allow-Methods: GET, PUT, POST, DELETE, HEAD. However, if you want to limit the endpoint to only a few methods, you should only include those methods.

As to why you haven't been seeing this before, this header is only used on CORS preflight requests. Maybe your application didn't use CORS preflight, and then something changed to trigger a preflight. Does your application use any HTTP methods other than GET/POST, or any custom HTTP headers?

You can learn more about CORS preflight requests here: http://www.html5rocks.com/en/tutorials/cors/

jameshfisher
  • 34,029
  • 31
  • 121
  • 167
monsur
  • 45,581
  • 16
  • 101
  • 95
  • Thanks for the correction. And to clarify, CORS still *does* work. I am wondering if I need it, in some case I am not testing for. – Paul Draper Dec 09 '13 at 19:47
  • Answered my question: "this header is only used on CORS preflight requests". – Paul Draper Dec 09 '13 at 19:55
  • where we can see the value of these headers? In my case i need to send a token in header but i can see only name not value – Taran Oct 12 '15 at 20:52
  • like i am seeing something like Access-Control-Request-Headers: dauth,content-type . No value for Dauth @monsur@paul – Taran Oct 12 '15 at 21:20
15

The default of Access-Control-Allow-Methods is to allow through all simple methods, even on preflight requests. As the flow on https://www.w3.org/TR/cors/#preflight-request says (step 7 of successful preflight request):

If request method is not a case-sensitive match for any method in methods and is not a simple method, apply the cache and network error steps.

And the definition of simple method is:

A method is said to be a simple method if it is a case-sensitive match for one of the following: GET HEAD POST

So if you have a preflighted POST request (due to a custom HTTP header, say), and do not send a Access-Control-Allow-Methods response header, the request will still go ahead okay.

M Somerville
  • 4,499
  • 30
  • 38
  • 2
    To be slightly more explicit here for readers, PATCH, DELETE, and PUT are NOT considered simple methods. Interestingly, I've found browser inconsistencies in how this is dealt with. Chrome opts to allow these methods when the `Access-Control-Allow-Methods` header is omitted, Firefox *does not*. – Jack Guy Jul 23 '18 at 20:17
  • Chrome allowing `PATCH` etc would be a bug, do you have an example/ have you reported it? I can't seem to reproduce it here. – M Somerville Jul 25 '18 at 06:56
  • In Chrome here I get e.g. `var xhr = new XMLHttpRequest(); xhr.open("GET", "https://mapit.mysociety.org/area/2514", true); xhr.send();` - works fine (site returns no A-C-A-M header). But `var xhr = new XMLHttpRequest(); xhr.open("PATCH", "https://mapit.mysociety.org/area/2514", true); xhr.send();` gives error: `Method PATCH is not allowed by Access-Control-Allow-Methods in preflight response.` – M Somerville Jul 25 '18 at 07:02
  • Ah I was actually sending `Access-Control-Allow-Methods: *` as a header which is accepted in Chrome but not in Firefox. The asterisk doesn't appear to be allowed by the spec. – Jack Guy Jul 25 '18 at 17:12
  • It is allowed by the spec, but not implemented in all browsers yet. See end of https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods for bug issue links (was added to Chrome in 63). – M Somerville Jul 31 '18 at 09:27