【问题标题】:How to S3 + Cloudfrond + 2 SPA react apps in subfolders?如何 S3 + Cloudfrond + 2 SPA 反应子文件夹中的应用程序?
【发布时间】:2020-05-24 02:21:23
【问题描述】:

我想使用 S3 + Cloudfront 在子文件夹中提供 2 个不同的 React 应用程序

myapp.com/app-one/ index.html
myapp.com/app-two/ index.html

我知道如何配置 create-react-app 和 react router 来处理这个问题。
https://create-react-app.dev/docs/deployment/#building-for-relative-paths

问题在于配置 S3 + Cloudfront 来处理重定向。

当您在浏览器中输入网址时:
myapp.com/app-one/some-route - 它应该重定向到 app-one 的 index.html
myapp.com/app-two/some-route - 它应该重定向到 app-two 的 index.html

不幸的是,S3 只允许您为Static website hosting 定义一个后备file.html (404)

我也不想用hashrouter:https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/docs/api/HashRouter.md

【问题讨论】:

  • 你找到解决办法了吗?

标签: reactjs amazon-s3 react-router single-page-application amazon-cloudfront


【解决方案1】:

我在 Angular 应用程序中遇到了同样的问题,并找到了一些解决方案,但我发现最有用的是使用 Lambda@Edge 函数,这允许您将静态文件保存在 S3 存储桶中,而无需开放静态托管。

唯一对我有用的 Lambda@Edge 配置是来自 this answer 的配置。代码如下:

var path = require('path');

exports.handler = (event, context, callback) => {
  // Extract the request from the CloudFront event that is sent to Lambda@Edge
  var request = event.Records[0].cf.request;

  const parsedPath = path.parse(request.uri);

  // If there is no extension present, attempt to rewrite url
  if (parsedPath.ext === '') {
    // Extract the URI from the request
    var olduri = request.uri;

    // Match any '/' that occurs at the end of a URI. Replace it with a default index
    var newuri = olduri.replace(/second-app.*/, 'second-app/index.html');

    // Replace the received URI with the URI that includes the index page
    request.uri = newuri;
  }
  // If an extension was not present, we are trying to load static access, so allow the request to proceed
  // Return to CloudFront
  return callback(null, request);
};

它的基本作用是匹配子文件夹的 uri 并将所有请求重定向到正确的 index.html 文件。如果您有多个子文件夹,您可以简单地添加一些条件:

var path = require('path');

exports.handler = (event, context, callback) => {
  // Extract the request from the CloudFront event that is sent to Lambda@Edge
  var request = event.Records[0].cf.request;

  const parsedPath = path.parse(request.uri);

  // If there is no extension present, attempt to rewrite url
  if (parsedPath.ext === '') {
    // Extract the URI from the request
    var olduri = request.uri;
    var newuri = olduri
    // Match any '/' that occurs at the end of a URI. Replace it with a default index
    if(olduri.match(/first-sub-app.*/)){
        newuri = olduri.replace(/first-sub-app.*/, 'first-sub-app/index.html');
    } else if(olduri.match(/second-sub-app.*/)){
        newuri = olduri.replace(/second-sub-app.*/, 'second-sub-app/index.html');
    }

    // Replace the received URI with the URI that includes the index page
    request.uri = newuri;
  }
  // If an extension was not present, we are trying to load static access, so allow the request to proceed
  // Return to CloudFront
  return callback(null, request);
};

查看原始答案以获取有关设置的更多说明以及有关其工作原理的更多详细信息,但它基本上会忽略任何带有扩展名的请求,并且仅在它与特定子目录匹配时才会重定向。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-28
    • 1970-01-01
    • 2017-07-10
    • 2019-06-24
    • 2015-01-11
    • 2020-04-28
    • 1970-01-01
    相关资源
    最近更新 更多