Access-Control-Allow-HeadersとCORS

あなたが新進の若い(または心の若い!)フロントエンド開発者だとしましょう。 次のHackathonプロジェクトのために、たくさんのサードパーティAPIをまとめたいと思います。 このAPIは見栄えがします: https://icanhazdadjoke.com/api ! 世界で次の素晴らしいオヤジギャグアプリを作成します! 興奮して、あなたは小さなアプリを作り上げます(これらの例はReactを使用していますが、原則はフレームワークに依存しません):

function App() {
  const [msg, setMsg] = React.useState("click the button")
  const handler = () =>
    fetch("https://icanhazdadjoke.com/", { headers: { accept: "Accept: application/json" } })
      .then((x) => x.json())
      .then(({ msg }) => setMsg(msg))

  return (
    <div className="App">
      <header className="App-header">
        <p>message: {msg}</p>
        <button onClick={handler}> click meeee</button>
      </header>
    </div>
  )
}

yarn startで新しいアプリをローカルでテストし、…

Access to fetch at 'https://icanhazdadjoke.com/' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field accept is not allowed by Access-Control-Allow-Headers in preflight response.

ああ、、あなたは思う、これは以前に見たことがありますが、どうすればこれをもう一度修正できますか?

グーグルで検索すると、このブラウザプラグインこのサーバーサイド修正このように長すぎるMDN記事と、単純なAPIリクエストには多すぎます。 まず、APIを制御できないため、CORSヘッダーを追加することは問題外です。 次に、この問題は、SSLを持たないhttp://localhostからhttps:// APIを使用しているために発生しているため、httpsはドメインを有効にしましたが、それでもローカル開発エクスペリエンスを解決できません。 最後に、あなたは何かを稼働させたいと思っていましたが、今はステップ1でグーグルの厄介なセキュリティ関連のもので立ち往生しています。

超イライラ。 デフォルトでのWebがますます増えているので、クライアント側のアプリで作業するときに、これに遭遇することが増えます(サーバー側のフレームワークが実際に直面しない理由の1つ)信頼できる環境で実行されるため、CORSの問題)。

Netlify Dev、ローカルプロキシソリューション

十分に長い間見て回った場合、CORSはブラウザ保護であり、制御しているサーバーからリクエストを行っただけでは完全には適用されないことに気付くでしょう。 つまり、プロキシサーバーを起動すると、すべての問題が解決します。 唯一の問題は、このプロキシを起動するのが難しすぎてコストがかかりすぎることです。 そして、それはローカル開発者のためだけです。 デプロイされたエクスペリエンスはまったく異なり、セットアップがさらに複雑になります。

過去数か月間、私は Netlify Dev に取り組んできました。これは、まさにこの種のユースケース向けの優れたプロキシサーバーになることを目的としています。 Netlify CLIに組み込まれており、ダウンロードできます。

$ npm i -g netlify-cli

プロジェクトで、create-react-app、Next.js、Gatsby、Vue-CLI、Nuxtなどの人気のあるプロジェクトであれば、次のコマンドを実行できるはずです。

# provide a build command and publish folder
# specific to your project,
# create a Netlify site instance, and
# initialize netlify.toml config file if repo connected to git remote
$ netlify init # or `ntl init`

# start local proxy server
$ netlify dev # or `ntl dev`

また、そのポートが使用可能な場合は、プロキシサーバーがlocalhost:8888で実行されていることを確認する必要があります。

プロジェクトがサポートされていない場合は、独自の構成を作成して提供できますが、大多数の人にとっては構成がゼロのエクスペリエンスになるはずです。

今のところ、プロジェクトを盲目的にプロキシするのはローカルプロキシサーバーであり、あまり印象的ではありません。 サーバーレス機能を起動する時が来ました!

Netlify関数の作成

この時点で、functionsフィールドを持つnetlify.tomlファイルが作成されているはずです。 必要に応じて自分で手書きすることもできますが、次のようになります。

[build]
  command = "yarn run build"
  functions = "functions"
  publish = "dist"

これらのそれぞれをニーズに合わせて構成できます。Netlifyのドキュメントを確認してください。 しかし、いずれにせよ、今あなたが実行するとき:

$ netlify functions:create

CLIは、関数テンプレートのリストを表示します。 node-fetchを選択すると、必要な依存関係のインストールを含め、デフォルトで/functions/node-fetchに新しいサーバーレス機能の足場が作成されます。 生成されたファイルを見てください、しかし最も重要なものはfunctions/node-fetch/node-fetch.jsでしょう。 慣例により、フォルダ名は、関数のエントリポイントが認識されるためのファイル名と一致する必要があります。

これで、APIを呼び出すサーバーレスNode.js関数ができました。 残りの唯一のことは、APIに直接アクセスするのではなく、フロントエンドを変更して関数プロキシにpingを実行することです。

const handler = () =>
  fetch("/.netlify/functions/node-fetch", { headers: { accept: "Accept: application/json" } })
    .then((x) => x.json())
    .then(({ msg }) => setMsg(msg))

ローカル開発でCORSを取り除く

プロキシサーバーを再度実行すると、次のようになります。

$ netlify dev # or ntl dev

そして、プロキシポート(通常はhttp://localhost:8888)に移動し、ボタンをクリックします…

message: Why can't a bicycle stand on its own? It's two-tired.

面白い! CORSの問題を取り除いたので、笑うことができます。

本番環境でのCORSの導入と排除

デプロイすると、ローカルプロキシは失われますが、本番環境を温かく受け入れることができます。これは、設計とまったく同じように機能します。

$ npm run build ## in case you need it
$ netlify deploy --prod ## this is the manual deploy process

そして、デプロイされたサイトに移動します(netlify open:siteを実行します)。

注:GitHub、GitLab、またはBitBucketからの継続的デプロイを介してサイトをデプロイする場合は、netlify.tomlビルドコマンドを変更して関数従属性をインストールする必要があります。

[build]
  command = "yarn build && cd functions/node-fetch && yarn"
  functions = "functions"
  publish = "dist"

これで、機密APIキー(プロジェクトがオープンソースの場合はハードコードされますが、これは行わないでください。または環境変数として)を使用して、文字通り任意のAPIをプロキシする関数を起動する方法がわかりました。数分でエンドユーザーに公開したくありません。 これは、本番CORSの問題を軽減するのにも役立ちますが、それらはよりまれです。

プロキシする単純なエンドポイントとファイルがある場合は、 Netlify Redirect Rewrites を使用して、1行で行ったことを実行することもできますが、もちろんカスタマイズ性は低くなります。

CORSの問題を一度に解決する方法はこれですべてです。 Netlify Devはまだベータ版であることに注意してください。問題が発生した場合や質問がある場合は、問題を報告してください