Open19

cors

kajirikajirikajirikajiri

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any other origins (domain, scheme, or port) than its own from which a browser should permit loading of resources. CORS also relies on a mechanism by which browsers make a “preflight” request to the server hosting the cross-origin resource, in order to check that the server will permit the actual request. In that preflight, the browser sends headers that indicate the HTTP method and headers that will be used in the actual request.

deepL
CORS(Cross-Origin Resource Sharing)とは、HTTPヘッダーに基づいたメカニズムで、ブラウザがリソースの読み込みを許可すべきサーバーのオリジン(ドメイン、スキーム、ポート)を、自分のオリジン以外にも示すことができます。また、CORSは、ブラウザがクロスオリジンのリソースをホストするサーバーに「プリフライト」リクエストを行い、サーバーが実際のリクエストを許可するかどうかをチェックするメカニズムにも依存しています。プリフライトでは、ブラウザは実際のリクエストで使用されるHTTPメソッドとヘッダを示すヘッダを送信します。

これ日本語でもむずいんだけど。こうだと思うな。違うかな。 than its own だから自分はサーバーのはず。

ブラウザがリソースの読み込みを許可すべき自分(サーバー)のオリジン以外のオリジンをサーバーが示すことができる。
サーバーがHTTPヘッダーに基づいたメカニズムでブラウザに示すことができる。
プリフライトでHTTPメソッドとヘッダを示すヘッダを送信。

MDNの日本語ページを見たけど、それも微妙だな。主語がない。

オリジン間リソース共有Cross-Origin Resource Sharing (CORS) は、追加の HTTP ヘッダーを使用して、あるオリジンで動作しているウェブアプリケーションに、異なるオリジンにある選択されたリソースへのアクセス権を与えるようブラウザーに指示するための仕組みです。

kajirikajirikajirikajiri

Additionally, for HTTP request methods that can cause side-effects on server data (in particular, HTTP methods other than GET, or POST with certain MIME types), the specification mandates that browsers "preflight" the request, soliciting supported methods from the server with the HTTP OPTIONS request method, and then, upon "approval" from the server, sending the actual request.

GET以外のHTTPメソッドや特定のMIMEタイプ??を持つPOSTはブラウザからサーバーにプリフライトが義務付けられている。
HTTP OPTIONSリクエストでサポートされているメソッドを要求??し、サーバーから承認をえた上でリクエストを送信。

kajirikajirikajirikajiri

Apart from the headers automatically set by the user agent (for example, Connection, User-Agent, or the other headers defined in the Fetch spec as a “forbidden header name”), the only headers which are allowed to be manually set are those which the Fetch spec defines as a “CORS-safelisted request-header”, which are:
Accept
Accept-Language
Content-Language
Content-Type (but note the additional requirements below)

意外と少ないんだな

kajirikajirikajirikajiri

The only allowed values for the Content-Type header are:
application/x-www-form-urlencoded
multipart/form-data
text/plain

こちらもこれしかないのか

kajirikajirikajirikajiri

Let's look at what the browser will send to the server in this case, and let's see how the server responds:

ここら辺から実際の動作

kajirikajirikajirikajiri

The example above creates an XML body to send with the POST request. Also, a non-standard HTTP X-PINGOTHER request header is set. Such headers are not part of HTTP/1.1, but are generally useful to web applications. Since the request uses a Content-Type of application/xml, and since a custom header is set, this request is preflighted.

なるほどなるほど

kajirikajirikajirikajiri

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests

CORSを定義しているFetchの仕様ではシンプルリクエストとは言わないが、リンク先のシンプルリクエストを満たしているものの場合は、シンプルに一回のやりとりで完了する。だが、CORSを判定しないわけではない。一回のやり取りでCORS判定をしてそのままレスポンスを返す。

kajirikajirikajirikajiri

シンプルリクエストでない場合、例でいえば、X-PINGOTHERというヘッダーが含まれている。このX-PINGOTHERはシンプルリクエストのヘッダー用件を満たしていない。なぜなら、シンプルリクエストでは以下のヘッダーしか認められていないから。

const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://bar.other/resources/post-here/');
xhr.setRequestHeader('X-PINGOTHER', 'pingpong');
xhr.setRequestHeader('Content-Type', 'application/xml');
xhr.onreadystatechange = handler;
xhr.send('<person><name>Arun</name></person>');
kajirikajirikajirikajiri

許可されているヘッダーだとしても、そのまま許可するわけではない。それぞれのヘッダーごとに用件を満たす必要がある。それぞれを満たした場合でも、許可されていないヘッダーの場合はfalseを返す。

kajirikajirikajirikajiri

例でいえば、ClientがX-PINGOTHERをヘッダーに追加している。これは先程のシンプルリクエストに一致しないので、最初にプリフライトリクエストをOPTIONSメソッドで行い、送信していいかをサーバーに判定してもらう。

As described below, the actual POST request does not include the Access-Control-Request-* headers; they are needed only for the OPTIONS request.

おーそうなのね。postでx-pingotherがヘッダーに入ってるけど大丈夫?って確認するってことだろう。そのプリフライトリクエストで許可が出れば、以降は不要な情報なので送信しないという感じかな。

Lines 1 - 10 above represent the preflight request with the OPTIONS method. The browser determines that it needs to send this based on the request parameters that the JavaScript code snippet above was using, so that the server can respond whether it is acceptable to send the request with the actual request parameters. OPTIONS is an HTTP/1.1 method that is used to determine further information from servers, and is a safe method, meaning that it can't be used to change the resource. Note that along with the OPTIONS request, two other request headers are sent (lines 9 and 10 respectively):

ブラウザが判定しているのか。
OPTIONSはリソースの変更には仕様できないことを意味する安全なメソッドなのか。

The server responds with Access-Control-Allow-Origin: https://foo.example, restricting access to just the requesting origin domain. It also responds with Access-Control-Allow-Methods, which says that POST and GET are viable methods to query the resource in question (this header is similar to the Allow response header, but used strictly within the context of access control).

postとgetが使えるよって返せるんだ。

Finally, Access-Control-Max-Age gives the value in seconds for how long the response to the preflight request can be cached for without sending another preflight request. In this case, 86400 seconds is 24 hours. Note that each browser has a maximum internal value that takes precedence when the Access-Control-Max-Age is greater.

プリフライトってキャッシュされるんや

kajirikajirikajirikajiri

Not all browsers currently support following redirects after a preflighted request. If a redirect occurs after a preflighted request, some browsers currently will report an error message such as the following.

全てのブラウザがプリフライトの後のリダイレクトに対応しているわけではないと

kajirikajirikajirikajiri

昔読んだ時は飛ばしながら読んだから理解できなかったんだな。今は読めるは