简体   繁体   English

AWS Cloudfront 作为具有自定义域的 Heroku 站点的 CDN

[英]AWS Cloudfront as CDN for Heroku Site with Custom Domain

Recently, I bought a domain from AWS Route 53 (brianpatrickhummel.com) to host a personal portfolio.最近,我从 AWS Route 53 (brianpatrickhummel.com) 购买了一个域来托管个人投资组合。 The portfolio site is up and running, using an S3 bucket and Cloudfront as a CDN.投资组合站点已启动并运行,使用 S3 存储桶和 Cloudfront 作为 CDN。 On the portfolio site, visitors are able to preview some apps that I built, which launch in-site using iframe elements, and I noticed that my Heroku-deployed apps take 10-20 seconds to load, since those sites have very few visitors on average and have no CDN service.在投资组合网站上,访问者可以预览我构建的一些应用程序,这些应用程序使用 iframe 元素在现场启动,我注意到我的 Heroku 部署的应用程序需要 10-20 秒才能加载,因为这些网站上的访问者很少平均并且没有 CDN 服务。

Therefore, I began researching using AWS Cloudfront as a CDN.因此,我开始研究使用 AWS Cloudfront 作为 CDN。 I began with one Heroku app, adding a custom domain which is now configured as such:我从一个 Heroku 应用程序开始,添加了一个自定义域,现在配置如下:

Domain Name: burger.brianpatrickhummel.com
DNS Target: burger.brianpatrickhummel.com.herokudns.com

The last step is to "configure your app's DNS provider to point to the Heroku-supplied DNS Target."最后一步是“将您的应用程序的 DNS 提供程序配置为指向 Heroku 提供的 DNS 目标”。 Between this step and properly configuring a Cloudfront distribution, I have run myself into a spiral of confusion.在这一步和正确配置 Cloudfront 发行版之间,我陷入了混乱的漩涡。 I'm uncertain as to of where I make certain DNS/CNAME changes, in Cloudfront, Route 53 or both.我不确定在 Cloudfront、Route 53 或两者中进行某些 DNS/CNAME 更改的位置。

There isn't much online documention specifically related to these three technologies (Heroku, Cloudfront, Route 53) and I've spent much time bouncing between these three articles, to no avail:没有太多与这三种技术(Heroku、Cloudfront、Route 53)相关的在线文档,我花了很多时间在这三篇文章之间跳来跳去,但无济于事:

Heroku - Using Amazon CloudFront CDN Heroku - 使用 Amazon CloudFront CDN

Configuring Amazon Route 53 DNS for Your Heroku App为您的 Heroku 应用程序配置 Amazon Route 53 DNS

I'm confident that the necessary changes are simple in nature and would greatly appreciate any insight from those who might have experience with this particular configuration.我相信必要的更改本质上很简单,并且非常感谢那些可能对这种特定配置有经验的人的任何见解。

---UPDATE--- ---更新---

I have one last question, now that I have all of my Heroku apps successfully routing through Cloudfront, I have realized that all of the apps which have components that generate POST HTTP requests receive 403 - forbidden errors.我还有最后一个问题,现在我的所有 Heroku 应用程序都通过 Cloudfront 成功路由,我意识到所有具有生成 POST HTTP 请求的组件的应用程序都会收到 403 - 禁止错误。 Does this have anything to do with the relative URL in the respective AJAX calls:这与相应 AJAX 调用中的相对 URL 有什么关系:

$(document).on("click", ".saveButton", function () {
  var thisId = $(this).attr("id");
  $.ajax({
    method: "POST",
    url: "/save/" + thisId
  }).done(function () {} 

I see the following in the Cloudfront documentation:我在 Cloudfront 文档中看到以下内容:

CloudFront always caches responses to GET and HEAD requests. CloudFront 始终缓存对 GET 和 HEAD 请求的响应。 You can also configure CloudFront to cache responses to OPTIONS requests.您还可以将 CloudFront 配置为缓存对 OPTIONS 请求的响应。 CloudFront does not cache responses to requests that use the other methods. CloudFront 不会缓存对使用其他方法的请求的响应。

Is this more of a problem with handling the responses from the server of the Heroku app than it is an issue with successfully sending the request?与成功发送请求相比,处理来自 Heroku 应用程序服务器的响应是否更像是一个问题?

-- UPDATE 2 -- -- 更新 2 --
I'm thinking that this has to do with HTTP/HTTPS based on this statement in the Cloudfront Documentation:我认为这与基于 Cloudfront 文档中的此声明的 HTTP/HTTPS 有关:

CloudFront doesn't redirect DELETE, OPTIONS, PATCH, POST, or PUT requests from HTTP to HTTPS. CloudFront 不会将 DELETE、OPTIONS、PATCH、POST 或 PUT 请求从 HTTP 重定向到 HTTPS。 If you configure a cache behavior to redirect to HTTPS, CloudFront responds to HTTP DELETE, OPTIONS, PATCH, POST, or PUT requests for that cache behavior with HTTP status code 403 (Forbidden).如果您将缓存行为配置为重定向到 HTTPS,CloudFront 会使用 HTTP 状态代码 403(禁止)响应该缓存行为的 HTTP DELETE、OPTIONS、PATCH、POST 或 PUT 请求。

Heroku states: Heroku 指出:

If you are wanting to serve Cloudfront assets using SSL you can simply use HTTPS on the distribution domain given to you by Amazon.如果您想使用 SSL 为 Cloudfront 资产提供服务,您只需在 Amazon 提供给您的分发域上使用 HTTPS。 Note, whilst you can create CNAME's for this purpose, serving Cloudfront assets over your CNAME and SSL has an attached cost.请注意,虽然您可以为此目的创建 CNAME,但通过 CNAME 和 SSL 提供 Cloudfront 资产会产生附加成本。

In AWS Cloudfront Distribution Cache Behaviour settings, you can choose for the Viewer Protocol Policy from three options:在 AWS Cloudfront Distribution Cache Behavior 设置中,您可以从三个选项中选择查看器协议策略

If you want CloudFront to allow viewers to access your web content using either HTTP or HTTPS, specify HTTP and HTTPS.如果您希望 CloudFront 允许查看者使用 HTTP 或 HTTPS 访问您的 Web 内容,请指定 HTTP 和 HTTPS。 If you want CloudFront to redirect all HTTP requests to HTTPS, specify Redirect HTTP to HTTPS.如果您希望 CloudFront 将所有 HTTP 请求重定向到 HTTPS,请指定将 HTTP 重定向到 HTTPS。 If you want CloudFront to require HTTPS, specify HTTPS Only.如果您希望 CloudFront 需要 HTTPS,请指定仅 HTTPS。

The Cloudfront doc goes on to note: Cloudfront 文档继续指出:

Redirect HTTP to HTTPS Viewers can use both protocols, but HTTP requests are automatically redirected to HTTPS requests.将 HTTP 重定向到 HTTPS查看器可以使用这两种协议,但 HTTP 请求会自动重定向到 HTTPS 请求。 CloudFront returns HTTP status code 301 (Moved Permanently) along with the new HTTPS URL. CloudFront 返回 HTTP 状态代码 301(永久移动)以及新的 HTTPS URL。 The viewer then resubmits the request to CloudFront using the HTTPS URL.然后,查看器使用 HTTPS URL 将请求重新提交到 CloudFront。

When a viewer makes an HTTP request that is redirected to an HTTPS request, CloudFront charges for both requests.当查看器发出重定向到 HTTPS 请求的 HTTP 请求时,CloudFront 会为这两个请求收费。 For the HTTP request, the charge is only for the request and for the headers that CloudFront returns to the viewer.对于 HTTP 请求,费用仅针对请求和 CloudFront 返回给查看器的标头。 For the HTTPS request, the charge is for the request, and for the headers and the object returned by your origin.对于 HTTPS 请求,费用针对请求、标头和源返回的对象。

HTTPS Only Viewers can access your content only if they're using HTTPS.仅 HTTPS 的查看者只有在使用 HTTPS 时才能访问您的内容。 If a viewer sends an HTTP request instead of an HTTPS request, CloudFront returns HTTP status code 403 (Forbidden) and does not return the object.如果查看器发送 HTTP 请求而不是 HTTPS 请求,CloudFront 将返回 HTTP 状态代码 403(禁止)并且不返回对象。

Good grief, I had no idea how complicated it would be to host a personal website!真悲哀,我不知道托管个人网站会有多复杂!

Domain Name: burger.brianpatrickhummel.com域名:burger.brianpatrickhummel.com

You will point this to CloudFront, in Route 53... but before you can do that, you need to create a new CloudFront distribution and configure that hostname as an Alternate Domain Name for the distribution.您将在 Route 53 中将此指向 CloudFront...但在此之前,您需要创建一个新的 CloudFront 分配并将该主机名配置为分配的备用域名。

DNS Target: burger.brianpatrickhummel.com.herokudns.com DNS 目标:burger.brianpatrickhummel.com.herokudns.com

Configure this as the Origin Domain Name when creating the distribution CloudFront.创建分配 CloudFront 时,将此配置为源域名。

In the Cache Behavior settings, whitelist the Host header so that Heroku will understand which site the request is for.在缓存行为设置中,将Host标头列入白名单,以便 Heroku 了解请求是针对哪个站点的。

Here are the steps I would do,这是我会做的步骤,

Since you are already on Route 53,由于您已经在 53 号公路上,

Get a free SSL from ACM从 ACM 获取免费 SSL

Confirm your SSL verification to the domain email address.确认您对域电子邮件地址的 SSL 验证。 Make sure it looks green as below,确保它看起来像下面的绿色,

ACM确认

Assign it to CloudFront Endpoint with the SSL and CNAME as well也使用 SSL 和 CNAME 将其分配给 CloudFront Endpoint

You will also see a cname will be automatically created in Route53 for this SSL endpoint.您还将看到将在 Route53 中为此 SSL 端点自动创建一个 cname。

If you ping burger.brianpatrickhummel.com, it should respond from the clound front.如果您 p​​ing burger.brianpatrickhummel.com,它应该从云前端响应。

云端 SSL

Now setup Origins in Cloudfront to point it to your endpoint with all the cache settings needed.现在在 Cloudfront 中设置 Origins 以将其指向具有所需的所有缓存设置的端点。 If you don't need cache settings, you can set them all to 0, so cloudfront will not cache any data.如果不需要缓存设置,可以全部设置为0,这样cloudfront就不会缓存任何数据。

In your Cloudront Pattern make sure you have * at the end so it matches all the url pattern to forward it to your endpoint.在您的 Cloudront 模式中,确保末尾有 *,以便它匹配所有 url 模式以将其转发到您的端点。

If your endpoint need to be secured, you can pass in additional headers from Cloudfront and make sure the request is orignating from cloudfront, rather than any public endpoint.如果您的端点需要保护,您可以从 Cloudfront 传入额外的标头,并确保请求来自 Cloudfront,而不是任何公共端点。

I'm uncertain as to of where I make certain DNS/CNAME changes, in Cloudfront, Route 53 or both我不确定在 Cloudfront、Route 53 或两者中进行某些 DNS/CNAME 更改的位置

Well since Route53 is the DNS service (not CloudFront), then you would be creating the CNAME record in Route53.既然 Route53 是 DNS 服务(不是 CloudFront),那么您将在 Route53 中创建 CNAME 记录。 You want to create a CNAME record in Route53 that points your subdomain to CloudFront.您想在 Route53 中创建一个 CNAME 记录,将您的子域指向 CloudFront。 Then you need to configure CloudFront to be aware that it needs to serve that domain by configuring the Alternate Domain Name field.然后,您需要将 CloudFront 配置为通过配置备用域名字段来了解它需要为该域提供服务。

It seems Host is no longer trusted and accepted by heroku .似乎Host 不再被 heroku 信任和接受 It will no longer link up to the site correctly它将不再正确链接到该站点

Use Origin Custom Header instead.请改用Origin Custom Header

The name of the custom header will go through some parsing and casing changes, so to debug it, add in this command to print the relevant headers provided in the request.自定义头的名称会经过一些解析和大小写更改,因此要对其进行调试,请添加此命令以打印请求中提供的相关头。

puts request.headers.env.reject { |key| key.to_s.include?('.') }

You should see your headers in there, but probably in a different format.你应该在那里看到你的标题,但可能是不同的格式。

For reference, my header was X-Request-ID (this is recommended by Heroku for its extra uses), and it was converted to HTTP_X_REQUEST_ID .作为参考,我的标头是X-Request-ID (这是Heroku 推荐用于额外用途的),并将其转换为HTTP_X_REQUEST_ID

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM