S3托管的Angular应用程序、Route53和基于查询字符串的自定义

S3托管的Angular应用程序、Route53和基于查询字符串的自定义,angular,amazon-web-services,amazon-s3,dns,amazon-route53,Angular,Amazon Web Services,Amazon S3,Dns,Amazon Route53,我有一个Angular应用程序托管在AWS S3中。 我的应用程序的外观基于客户机查询字符串 www.example.com?client=test1 www.example.com?client=test2 现在我要做的是创建一个新的Route53记录test2.example.com,并将其指向我的Angular应用程序并注入查询字符串,因此test2.example.com解析为与www.example.com?client=test2相同。我有一个Python应用程序,我使用它做了类

我有一个Angular应用程序托管在AWS S3中。 我的应用程序的外观基于
客户机
查询字符串

  • www.example.com?client=test1
  • www.example.com?client=test2

现在我要做的是创建一个新的Route53记录
test2.example.com
,并将其指向我的Angular应用程序并注入查询字符串,因此test2.example.com解析为与www.example.com?client=test2相同。

我有一个Python应用程序,我使用它做了类似的事情,并使用API网关和自定义域来实现所需的结果。在我们的例子中,显示/设计CSS和JS资产相当复杂,位于不同的域和文件夹路径中。此外,html在服务器端呈现。我可能需要更详细地介绍一下您的用例,以便提供更定制的解决方案

由于Angular是所有客户端,我认为您可以将Route53指向所有子域的相同S3/Cloudfront端点,并让Angular应用程序将子域检测到变量中,或从函数返回子域值。然后在“主题”资产的文件夹路径中使用该值。您可以将所有主题资产存储到一个单独的S3存储桶中,仅用于此目的

类似这样的内容来获取子域值:

getSubdomain() {
  const domain = window.location.hostname;
  if (domain.indexOf('.') < 0 || 
    domain.split('.')[0] === 'example' || domain.split('.')[0] === 'lvh' || domain.split('.')[0] === 'www') {
    this.subdomain = '';
  } else {
    this.subdomain = domain.split('.')[0];
  }
  console.log('subdomain', this.subdomain);

  return this.subdomain;
}
 loadScripts() {
    const dynamicScripts = [
     'https://my-s3-asset-bucket-url/'+getSubdomain()+'/js/test1.js',
     'https://my-s3-asset-bucket-url/'+getSubdomain()+'/js/test1-more-stuff.js'
    ];
    for (let i = 0; i < dynamicScripts.length; i++) {
      const node = document.createElement('script');
      node.src = dynamicScripts[i];
      node.type = 'text/javascript';
      node.async = false;
      node.charset = 'utf-8';
      document.getElementsByTagName('head')[0].appendChild(node);
    }
  }

 loadCSS() {
    const dynamicLinks = [
     'https://my-s3-asset-bucket-url/'+getSubdomain()+'/css/test1.css',
     'https://my-s3-asset-bucket-url/'+getSubdomain()+'/css/test1-more-stuff.css'
    ];
    for (let i = 0; i < dynamicLinks.length; i++) {
      const node = document.createElement('link');
      node.href = dynamicLinks[i];
      node.type = 'text/css';
      node.rel ='stylesheet';
      document.getElementsByTagName('head')[0].appendChild(node);
    }
  }
取自和修改自

您还可以将上面的my-s3-asset-bucket-url更改为Cloudfront分发url。

您将无法在DNS解析期间“注入”查询字符串。相反,您需要某种重定向机制。一些想法:

  • 正如同事Aaron回答的那样,一个想法是在前端获取子域(window.location.hostname),并使用它从另一个源动态获取JS/CSS文件。或者,如果您不能将资产组织为“主题”,或者如果这不是您的用例,您可以在获得子域后执行以下操作,例如,对于test1子域:

    window.location.replace("http://www.example.com?client=test1");
    
  • 重定向也可以由后端/服务器代码执行,以防无法更改/自定义前端。AWS使用一个简单的S3 bucket作为重定向器,这是一个很好的选择,以防您无法更改后端。请注意,如果您在testX.example.com域中使用HTTPS,可能需要一些涉及CloudFront的附加步骤:

  • 下面是它的工作原理:

  • 浏览器(如web浏览器)提交对域(如example.com)的请求

  • Amazon Route 53将请求例如发送到Amazon CloudFront分发版

  • AmazonCloudFront将请求转发到指定为分发源的AmazonS3存储桶。水桶里没有你的内容;相反,当您创建bucket时,您将其配置为将请求重定向到另一个域名

  • AmazonS3使用HTTPS向CloudFront返回HTTP 301/302状态代码,以及您希望将流量重定向到的域的名称,例如example.net

  • CloudFront将重定向返回到查看器

  • 因为来自S3的响应使用HTTPS,所以CloudFront使用HTTPS将响应返回给查看器。AWS证书管理器(ACM)提供SSL/TLS证书,用于加密CloudFront和查看器之间的通信

  • 查看器提交对example.net的请求

  • DNS服务(例如.net)将请求路由到适用的资源,例如另一个S3 bucket或运行web服务器的EC2实例

  • window.location.replace("http://www.example.com?client=test1");