访问控制允许头和CORS
假设你是一个年轻的(或年轻的心!)前端开发者。你真的很喜欢为你的下一个Hackathon项目组合一堆第三方API。这个API看起来很棒: https://icanhazdadjoke.com/api!我们将在世界上构建下一个伟大的Dad Joke应用程序! 令人兴奋的是,你会发起一个小应用程序(这些例子使用React,但原则是框架无知):
1function App() {
2 const [msg, setMsg] = React.useState("click the button")
3 const handler = () =>
4 fetch("https://icanhazdadjoke.com/", { headers: { accept: "Accept: application/json" } })
5 .then((x) => x.json())
6 .then(({ msg }) => setMsg(msg))
7
8 return (
9 <div className="App">
10 <header className="App-header">
11 <p>message: {msg}</p>
12 <button onClick={handler}> click meeee</button>
13 </header>
14 </div>
15 )
16}
你兴奋地开启
测试你的新应用本地,并...
1Access 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上抓住了Gocky i。
现在,当你在客户端应用程序上工作时(一个原因是服务器侧框架实际上甚至没有面对CORS问题)时,你会越来越多地投入其中。
Netlify Dev,本地代理解决方案
如果你回顾了足够长的时间,你会注意到CORS是一种浏览器保护,如果你刚刚从你控制的服务器发出请求,则完全不适用。换句话说,翻转代理服务器,所有的问题都消失了。
在过去的几个月里,我一直在开发 Netlify Dev,该服务器旨在成为一个非常好的代理服务器,用于这种类型的使用。
1$ npm i -g netlify-cli
现在在您的项目中,如果它是 我们支持的流行的项目,如create-react-app,Next.js,Gatsby,Vue-CLI,Nuxt等,您应该能够运行:
1# provide a build command and publish folder
2# specific to your project,
3# create a Netlify site instance, and
4# initialize netlify.toml config file if repo connected to git remote
5$ netlify init # or `ntl init`
6
7# start local proxy server
8$ netlify dev # or `ntl dev`
您应该看到代理服务器在localhost:8888
上运行,如果该端口可用。
如果您的项目不受支持,则 您可以编写并贡献自己的 config,但对于绝大多数人来说,它应该是一个零 config 体验。
截至目前,它是一个本地代理服务器,只是盲目地代理您的项目,没有什么令人印象深刻的。
创建一个 Netlify 函数
在这一点上,你应该有一个 netlify.toml
文件,其中包含一个 functions
字段. 如果你愿意,你可以手写自己的文件,但它应该看起来像这样:
1[build]
2 command = "yarn run build"
3 functions = "functions"
4 publish = "dist"
您可以根据您的需求配置每一个,只需 检查 Netlify 文档。
1$ netlify functions:create
CLI 會顯示函數模板列表,選擇「node-fetch」並為您預設在「/functions/node-fetch」中開啟一個新的無伺服器函數,包括安裝任何所需的依賴。 看看生成的檔案,但最重要的是「functions/node-fetch/node-fetch.js」。
很棒,所以我们现在有一个无服务器的Node.js函数,使我们的呼叫到API. 剩下的唯一事情是修改我们的前端来 ping我们的函数代理,而不是直接击中API:
1const handler = () =>
2 fetch("/.netlify/functions/node-fetch", { headers: { accept: "Accept: application/json" } })
3 .then((x) => x.json())
4 .then(({ msg }) => setMsg(msg))
在地方发展中摆脱CORS
现在,当我们再次运行代理服务器时:
1$ netlify dev # or ntl dev
然后前往代理端口(通常是http://localhost:8888`),然后点击...
1message: Why can't a bicycle stand on its own? It's two-tired.
搞笑!我们现在可以笑,因为我们已经摆脱了我们的CORS问题。
在生产中部署和摆脱 CORS
在部署时,我们失去了本地代理,但获得了生产环境的温暖拥抱,该环境(https://www.netlify.com/blog/2019/04/09/netlify-dev--our-entire-platform-right-on-your-laptop/)将以完全相同的方式工作。
1$ npm run build ## in case you need it
2$ netlify deploy --prod ## this is the manual deploy process
然后转到部署的网站(运行netlify open:site
)。
注意:如果您正在通过GitHub,GitLab或BitBucket的连续部署部署您的网站,您将需要修改netlify.toml
构建命令以安装函数依赖: <$>
1[build]
2 command = "yarn build && cd functions/node-fetch && yarn"
3 functions = "functions"
4 publish = "dist"
现在你知道如何将一个函数转换为代理程序,并在几分钟内使用机密的 API 密钥(无论是硬代码,尽管如果你的项目是开源的,但不要这样做,或者作为 环境变量)你不想暴露给最终用户,这有助于缓解任何生产 CORS 问题,尽管这些更罕见。
如果你有简单的端点和代理文件,你也可以选择使用Netlify Redirect Rewrites(https://www.netlify.com/docs/redirects/?utm_source=blog&utm_medium=alligatorio&utm_campaign=devex#proxying)来完成我们刚刚在一行做的事情,但它当然不太可自定义。
这就是解决 CORS 问题的一切! 请注意,Netlify Dev 仍然处于测试阶段,如果您遇到任何问题或有任何问题,请提交一个问题(https://github.com/netlify/netlify-dev-plugin/)!