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ヘッダーを追加することは問題外です。 第二に、この問題はあなたが https://
からのAPI http://localhost
、SSLがないため、にデプロイすると問題が解決する可能性があります 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関数の作成
この時点で、netlify.tomlファイルがあります。 functions
分野。 必要に応じて自分で手書きすることもできますが、次のようになります。
[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コマンド:
[build]
command = "yarn build && cd functions/node-fetch && yarn"
functions = "functions"
publish = "dist"
これで、機密APIキー(プロジェクトがオープンソースの場合はハードコーディングされますが、これは行わないでください。または環境変数として)を使用して、文字通り任意のAPIをプロキシする関数を起動する方法がわかりました。数分でエンドユーザーに公開したくありません。 これは、本番CORSの問題を軽減するのにも役立ちますが、それらはよりまれです。
プロキシする単純なエンドポイントとファイルがある場合は、 Netlify Redirect Rewrites を使用して、1行で行ったことを実行することもできますが、もちろんカスタマイズ性は低くなります。
CORSの問題を一度に解決する方法はこれですべてです。 Netlify Devはまだベータ版であることに注意してください。問題が発生した場合や質問がある場合は、問題を報告してください。