Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
226 views
in Technique[技术] by (71.8m points)

javascript - Preflight request is sent with all methods

My FE application is using API from different domain. I know that it should trigger CORS, but as I understood it shouldn't create preflight for every request.

According to docs, I shouldn't have preflight request for GET method.

 Cross-site requests are preflighted like this since they may have implications to 
 user data. In particular, a request is preflighted if:

    - It uses methods other than GET, HEAD or POST. 
Also, if POST is used to send request data with a Content-Type 
other than application/x-www-form-urlencoded, multipart/form-data, 
or text/plain, e.g. if the POST request sends an XML payload to the
server using application/xml or text/xml, then the request is preflighted.
    - It sets custom headers in the request 
(e.g. the request uses a header such as X-PINGOTHER)

However, every request that I'm sending, has preflight (OPTIONS) request, no matter if it's GET or POST, and I find it strange (according to what docs said).

I set some headers (and I'm sending it with withCredentials: true), but I don't see that it should be the issue:

  headers.append('Access-Control-Allow-Origin', FRONTEND_URL);
  headers.append('Accept', 'application/json');
  headers.append('Content-Type', 'application/json');
  headers.append('Authorization', this._generateApiKey());
  headers.append('Language', this._languageISOCode);

Am I missing something?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

See https://developer.mozilla.org/docs/Web/HTTP/Access_control_CORS#Simple_requests

A CORS preflight OPTIONS request can be triggered just by adding a Content-Type header to a request — if the value’s anything except application/x-www-form-urlencoded, text/plain, or multipart/form-data. And that’s true even for GET requests (though you should never add a Content-Type header to a GET — because there’s no request body, so it serves no purpose).

And among the headers shown in the question, the Authorization header will also trigger a preflight, as will the "Language" header (which isn’t even a standard header name; maybe Accept-Language was intended?), and the Access-Control-Allow-Origin header (which isn’t even a request header; it’s a response header that should never be used in frontend code).

As far as the headers that don’t trigger a preflight: the Fetch spec (which defines CORS behavior) specifies what it calls a CORS-safelisted request-header, and defines as one of:

  • Accept
  • Accept-Language
  • Content-Language
  • Content-Type whose value, once parsed, has a MIME type (ignoring parameters) that is application/x-www-form-urlencoded, multipart/form-data, or text/plain

Any request — including any GET request — which contains a header that’s not among those CORS-safelisted request-headers listed above will trigger a preflight.


To help make all that more clear, I updated the MDN docs about CORS “simple requests” and the MDN docs about CORS preflighted requests (it’s slightly more complicated than what’s described above, actually—but what’s above suffices for the context of this question).


Note that WebKit/Safari places additional restrictions on the values allowed in the Accept, Accept-Language, and Content-Language headers.

If any of those headers have ”non-standard” values, WebKit/Safari will do a preflight.

As far as what WebKit/Safari considers “non-standard” values for those headers, that’s not really documented except in the following WebKit bugs:

No other browsers impose those extra restrictions, because they’re not part of the spec. They were unilaterally added to WebKit with no discussion with the spec editor or other browsers.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...