CORS、プリフライト要求およびオプション方法


前提


このポストは、最小限の文脈を与えて、しばしば不透明と考えられる話題の方へ若干の好奇心を浸透させる目的で軽い読書であるように意図されています- Corsはあらゆるウェブ開発者が簡単に理解することができる単純なHTTPヘッダーメカニズムです.
まず、あなたはSame-origin Policy . それは1つの起源のスクリプトがどのように他の上で資源と相互に作用するかを制限するビルトイン内蔵メカニズムです.

同じ起源🏠🏠


最も簡単な場合から始めましょう.リソースを保持しているサーバーと、それを要求するクライアントの両方が同じorigin ( <scheme>://<hostname><port> ).
サーバがhttp://localhost:3000 そしてHTTP GET / HTMLファイルを返します.

For the sake of brevity, the code examples only show what I want to focus on. If something is not clear, use the various Accompanying source code (same-origin) you'll find.


server.js
server.get("/", (_, reply) => {
  reply.sendFile("index.html");
});

server.get("/me", (_, reply) => {
  reply.status(200).send({ nickname: "didof" });
});
クライアントに到着したHTMLは、ルートに関連したリソースのためにサーバーを同じ起源に尋ねます/me 画面上のニックネームを示します.
index.html
<p>Nickname: <output></output></p>

<script>
    // This runs on http://localhost:3000
    fetch("/me") // fetch("http://localhost:3000/me")
    .then((res) => res.json())
    .then((res) => {
        document.querySelector("output").textContent = res.nickname;
    });
</script>
ペイロードは、元のポリシーが尊重されるときにアクセスできます.Corsの必要は、プリフライトの要求の必要はありません.

起源🏠🏭


今クライアントが公開されますhttp://localhost:8000 リソースを持つサーバーがhttp://localhost:3000 . スキームとホスト名が同じであっても、ポートは異なっています-したがって、それらは2つの異なる起源です.

In the real world, the following concept is found when the client on https://mywebsite.com requires a resource to http://api.foo.it/bar


Accompanying source code (cross-origin)


index.html
<script>
// This runs on http://localhost:8000
const request = new Request("http://localhost:3000/me", {
  method: "GET",
});

fetch(request)
.then((res) => res.json())
.then((res) => { ... })
</script>
あなたが推測できるように、あなたはCORS エラーです.

コンソールのエラーは、問題をはっきりと説明します.それを直しましょう.サーバでは,corsを管理する.
server.js
server.register(fastifyCors, {
  origin: "http://localhost:8000",
});

I use fastify here, but any framework offers its own way of managing CORS. It's just headers added to the response, nothing more - you can of course append them manually.


今、応答はaccess-control-allow-origin 値はhttp://localhost:8000 .

サーバは基本的に応答を展開するリクエストを発行したブラウザに許可を与えます.

予備飛行要求🏠✉️🏭


CORSリクエストには次の2種類があります.
  • 単純な要求
  • 予備飛行要求
  • ブラウザによって決定されます.この瞬間まで、クライアントは、彼らが合うので、単純な要求をしましたcriteria .
    このポストの目的のために、あなたはそれを知っている必要があるだけである、あなたはちょうど要求をカスタムヘッダーに加える必要がある前飛行要求をブラウザーに強制します.

    Accompanying source code (cross-origin-preflight)


    index.html
    <script>
    const headers = new Headers();
    headers.append("X-CUSTOM-HEADER", "foo");
    
    // This runs on http://localhost:8000
    const request = new Request("http://localhost:3000/me", {
      method: "GET",
      headers,
    });
    
    fetch(request)
      .then((res) => res.json())
      .then((res) => { ... })
    
    そして、それはブラウザが1つの代わりに2つの要求を発射するのに十分です.

    使用法は OPTIONS , 定義された情報についてのクエリとしてサーバによって解釈されるrequest url .
    ブラウザはまた、プリフライトリクエストにヘッダを追加します.Access-Control-Request-Headers and Access-Control-Request-Method を比較します.

    ブラウザはサーバーに許可を求めているGET 様々なヘッダの中にあるリクエストもX-CUSTOM-HEADER .
    非常に許容されるように構成されているこの特定のサーバはaccess-control-allow-headers その値は要求されたものとaccess-control-allow-methods を指定します.

    それは大きな親指を与えている👍. ブラウザは、要求された要求を実行することができます.
    明らかに、何らかの理由でサーバがカスタムヘッダーの存在を許容しないように指示された場合、エラーが発生します.

    前述のように、これは単純なチャットです.興味があれば、以下のいくつかの参照がさらに行きます.私💖 HTMLのH!

    資源🕳️🐇

  • CORS Tutorial: A Guide to Cross-Origin Resource Sharing
  • Same-origin policy
  • CORS
  • Fetch API
  • Accompanying GitHub source code
  • 連絡を取る


  • 🐙 GitHub