我在AWS S3中托管了Angular应用。我的应用程序的外观基于client
查询字符串。
现在我要做的是创建一个新的Route53记录test2.example.com
,并使其指向我的Angular应用并注入查询字符串,因此test2.example.com解析为与www.example.com?client相同。 = TEST2。
我有一个与Python类似的应用,并且将API Gateway与Custom Domains结合使用以实现所需的结果。在我们的案例中,显示/设计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;
}
从How to handle tenant subdomains in Angular 2 (router 3)修改并修改
将子域值与以下内容一起使用:
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);
}
}
然后在您的构造函数中:
constructor() {
this.loadScripts();
this.loadCSS();
}
从How to load external scripts dynamically in Angular?修改并修改
您还可以将上面的my-s3-asset-bucket-url更改为Cloudfront发行版URL。
在DNS解析期间,您将无法“注入”查询字符串。相反,您需要某种redirection机制。一些想法:
正如同事亚伦(Aaron)回答的那样,一个想法是在前端获得一个子域(window.location.hostname),并使用该子域从另一个来源动态地获取JS / CSS文件。另外,如果您不能将资产组织为“主题”,或者如果这不是您的用例,则可以在获得子域后简单地执行JS redirect,例如对于test1子域:window.location.replace("http://www.example.com?client=test1");
重定向也可能由您的后端/服务器代码执行,以防您无法更改/自定义前端。 AWS的this interesting blog page使用简单的S3存储桶作为重定向器,如果您无法更改后端,这是一个不错的选择。请注意,如果您对testX.example.com域使用HTTPS,则可能需要一些涉及CloudFront的其他步骤:https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/tutorial-redirecting-dns-queries.html
这是它的工作方式:
查看器,例如网络浏览器,提交对诸如example.com之类的域的请求。
Amazon Route 53将对example.com的请求路由到Amazon CloudFront发行版。
Amazon CloudFront将请求转发到您指定为分发来源的Amazon S3存储桶。该存储桶不包含您的内容;相反,当您创建存储桶时,您将其配置为将请求重定向到另一个域名。
Amazon S3使用HTTPS将HTTP 301/302状态代码以及您要将流量重定向到的域的名称(例如example.net。)返回给CloudFront。
CloudFront将重定向返回到查看器。
因为来自S3的响应使用HTTPS,所以CloudFront使用HTTPS将响应返回给查看器。 AWS Certificate Manager(ACM)提供SSL / TLS证书,该证书对CloudFront与查看器之间的通信进行加密。
查看者提交了对example.net的请求。
DNS服务example.net将请求路由到适用的资源,例如另一个S3存储桶或运行Web服务器的EC2实例。