Skip to main content

在开发中代理 API 请求

注意: react-scripts@0.2.3 及更高版本提供此功能。

人们通常使用与后端实现相同的主机和端口来为前端 React 应用程序提供服务。

例如,部署应用程序后,生产设置可能如下所示:

/             - 静态服务器返回带有 React 应用程序 /todos 的 index.html - 静态服务器返回带有 React 应用程序 /api/todos 的 index.html - 服务器使用后端实现处理任何 /api/* 请求

不需要这样的设置。 但是,如果你确实有这样的设置,那么编写像 fetch('/api/todos') 这样的请求会很方便,而不必担心在开发过程中将它们重定向到另一个主机或端口。

要告诉开发服务器将任何未知请求代理到开发中的 API 服务器,请将 proxy 字段添加到 package.json,例如:

  "proxy": "http://localhost:4000",

这样,当你在开发中 fetch('/api/todos') 时,开发服务器会识别它不是静态资产,并将你的请求代理到 http://localhost:4000/api/todos 作为后备。 开发服务器将尝试将其 Accept 标头中没有 text/html 的请求发送到代理。

方便的是,这在开发中避免了 CORS 问题 和这样的错误消息:

Fetch API cannot load http://localhost:4000/api/todos. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

请记住,proxy 仅在开发中有效(使用 npm start),你需要确保像 /api/todos 这样的 URL 指向生产中的正确内容。 你不必使用 /api 前缀。 任何没有 text/html 接受标头的无法识别的请求将被重定向到指定的 proxy

proxy 选项支持 HTTP、HTTPS 和 WebSocket 连接。

如果 proxy 选项对你来说不够灵活,你也可以:

配置代理后出现 "Invalid Host Header" 错误

当你启用 proxy 选项时,你选择了一组更严格的主机检查。 这是必要的,因为让后端对远程主机开放会使你的计算机容易受到 DNS 重新绑定攻击。 this articlethis issue 中解释了该问题。

这应该不会影响你在 localhost 上开发,但是如果你像 described here 一样远程开发,你会在启用 proxy 选项后在浏览器中看到这个错误:

主机标头无效

要解决此问题,你可以在项目根目录中名为 .env.development 的文件中指定公共开发主机:

HOST=mypublicdevhost.com

如果你现在重新启动开发服务器并从指定的主机加载应用程序,它应该可以工作。

如果你仍然遇到问题,或者如果你使用的是云编辑器等更奇特的环境,你可以通过向 .env.development.local 添加一行来完全绕过主机检查。 请注意,这很危险,并且会使你的计算机暴露于来自恶意网站的远程代码执行:

# NOTE: THIS IS DANGEROUS!
# It exposes your machine to attacks from the websites you visit.
DANGEROUSLY_DISABLE_HOST_CHECK=true

我们不推荐这种方法。

手动配置代理

注意: react-scripts@2.0.0 及更高版本提供此功能。

如果 proxy 选项对你来说不够灵活,你可以直接访问 Express 应用程序实例并连接你自己的代理中间件。

你可以将此功能与 package.json 中的 proxy 属性结合使用,但建议你将所有逻辑合并到 src/setupProxy.js 中。

首先,使用 npm 或 Yarn 安装 http-proxy-middleware

$ npm install http-proxy-middleware --save
$ # or
$ yarn add http-proxy-middleware

接下来,创建 src/setupProxy.js 并将以下内容放入其中:

const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function (app) {
// ...
};

你现在可以根据需要注册代理! 下面是使用上述 http-proxy-middleware 的示例:

const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function (app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:5000',
changeOrigin: true,
})
);
};

注意:你不需要在任何地方导入此文件。 当你启动开发服务器时,它会自动注册。

注意:此文件仅支持 Node 的 JavaScript 语法。 确保只使用支持的语言特性(即不支持 Flow、ES 模块等)。

注意: 将路径传递给代理函数允许你在路径上使用 globbing 和/或模式匹配,这比快速路由匹配更灵活。