首页 > 解决方案 > 作为反应,我如何将后端 REST API 传递给我的前端?

问题描述

这里的问题很幼稚,我不想受到抨击。 我使用 create-react-app 创建了前端,并且正在使用 fetch 将后端 API 传递给我的前端。后端与前端在同一台机器上的 localhost:8080 上运行。前端在端口 3000 上运行。我已将 URL 硬编码为“ http://localhost:8080/getForm ”等等。如果我在托管的同一台机器上访问前端,这一切都很好。但是,如果我从另一台机器访问前端,API 调用会失败,这是有道理的,因为调用是针对 localhost。

现在,传递与机器无关的其余 URL 的最佳方法是什么?我不想为我的后端设置静态 IP。我努力了:

  1. 进行生产构建并将其与后端捆绑在一起。这再次调用了访问机器上的 localhost,但失败了。
  2. 使用 window.location.hostname+"getForm" 操作 URL。当我有不同的服务器托管前端和后端时,这会失败。

编辑* 好的,我通过将以下行添加到 package.json 来设法将代理添加到节点服务器。 "proxy":"http://localhost:8080/" 这会将前端的 localhost:3000/api/getForm 之类的内容转发到后端的 localhost:8080/api/getForm。这工作得很好,但现在我被困在一个我认为是由于不正确的 CORS 设置引起的问题上。代理 GET 请求到后端,这是一个 Spring Boot API,工作正常,但代理 POST 请求返回 403,响应“无​​效 CORS 请求”。

我已将 @CrossOrigin(origins="http://localhost:3000") 添加到我的 spring 应用程序的类级别,这应该使所有 apis CORS 友好。另外,我在前端使用 fetch 来拨打电话。关于我可能出错的任何线索?

POST /api/post HTTP/1.1 主机:localhost:3000 连接:keep-alive 内容长度:22 来源:http://localhost:3000 用户代理:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML , 像 Gecko) Chrome/67.0.3396.87 Safari/537.36 Content-Type: application/json Accept: / Referer: http://localhost:3000/ Accept-Encoding: gzip, deflate, br Accept-Language: en-IN,en -GB;q=0.9,en-US;q=0.8,en;q=0.7

正文 - {"title":"abc","body":"def"}

响应 - 403,无效的 CORS 请求

GET /api/get HTTP/1.1 Host: localhost:3000 Connection: keep-alive User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36 Accept: / Referer: http://localhost:3000/ Accept-Encoding: gzip, deflate, br Accept-Language: en-IN,en-GB;q=0.9,en-US;q=0.8,en;q=0.7

响应 - 200, [{"id":1,"title":"Post 1","body":"后端连接良好,花花公子!"}]

标签: reactjsrestfetchcreate-react-app

解决方案


当您不使用节点提供代码时,您可以使用 webpack 添加全局变量,但是您需要为每个环境创建单独的构建。

将 Node 与 SSR 一起使用时:

我通常做的是使用 .env 文件,其中包含主机名、端口、.. 的特定常量,并在 js 配置文件中使用这些常量。然后您可以导入该 js 文件并将其用于您的 fetch 调用。您可以使用 dotenv ( https://www.npmjs.com/package/dotenv ) 将 .env 变量添加到您的节点进程。

配置文件:

const config = {
  env: {
    host: (envConfig && envConfig.API_HOST) || 'localhost',
    port: (envConfig && envConfig.API_PORT) || '8000',
    httpOrigin: (envConfig && envConfig.API_PROTOCOL) || 'http'
  }
}

export default config;

.env 文件:

API_PROTOCOL=https
API_HOST=localhost
API_PORT=8000

要将配置传输到前端,您可以在 html 正文中进行序列化,然后在客户端渲染中获取它。

<script dangerouslySetInnerHTML={{ __html: `window.__envConfig=${serialize(envConfig)};` }} charSet="UTF-8"/>

推荐阅读