AWS API 网关:为什么调用 url 返回 HTML 代码而不是实际网页?

AWS API gateway: why is the invoke url returning HTML code instead of actual web page?

我正在 AWS 中构建我的应用程序。

我已经在 EC2 实例中部署了我的 Reactjs 前端项目。我不想让来自外部互联网世界的用户直接访问我的 EC2 实例,而是将其置于 AWS API 网关之后。因此 AWS API 网关将成为我的应用程序的前端和后端服务的单一入口点。

在对如何连接 API 网关和 EC2 实例进行一些研究后,我认为这是要采用的计划:

外部世界 ---> AWS API 网关 ---> VPC 链接 ---> 网络负载均衡器 ---> 我的 VPC 目标组/EC2 实例

这是我所做的:

  1. Reactjs 前端项目在 EC2 实例中 运行 很好;我可以用EC2实例的public ip地址访问网页。

  2. 目标组和网络负载均衡器配置良好。我通过在浏览器中输入 NLB 的 DNS 名称进行确认,即 http://myapp-frontend-NLB-c11112esd43524rw.elb.ap-northeast-1.amazonaws.com,它成功加载/打开了我的应用程序的前端网页。

  3. 我已遵循此 aws 文档:https://docs.aws.amazon.com/apigateway/latest/developerguide/getting-started-with-private-integration.html 逐步配置 VPC link、API 资源、集成类型等

    我只创建了一个 API:ANY / ,它接受基本路径上的任何方法,应该将 HTTP 请求传递给网络负载均衡器,然后传递给 EC2 实例。

    部署创建的API后,点击打开InvokeURL,(形式为https://123qwe123qe.execute-api.ap-northeast-1.amazonaws.com/[stage]),可以看到如下HTML代码:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="/favicon.ico" />
   
    ...

    <title>MY APP Title Name String</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
  <script src="/static/js/bundle.js"></script><script src="/static/js/vendors~main.chunk.js"></script><script src="/static/js/main.chunk.js"></script></body>
</html>

API 有效,因为响应包含 <title>MY APP Title Name String</title> 字符串。它必须已成功访问我的 EC2 实例上的前端服务 运行。


问题: 为什么我会得到 HTML 代码模板,但无法看到网页 UI,就像我在 NLB 的域 link 中看到的那样(就像在第 1 步和第 2 步中一样)?

为什么浏览器显示带有调用 url 的 HTML 代码,而不是使用 NLB 的 public url 加载实际网页 UI和 EC2 实例的 public ip 地址?

您需要在 API 网关的响应中设置适当的 Content-Type header。如果缺少 header 定义,则默认值为 application/json,因此您的浏览器会将您的 HTML 显示为文本,而不会正确呈现。

将 header Content-Type: text/html 添加到为 React 应用程序提供服务的路由,浏览器将正确显示它。