无缓存模式的云端

cloudfront in no caching mode

我正在构建一个无服务器应用程序,我的 SPA 托管在 S3 上,我的 APIs 在 lambda 前端由 API 网关结束。很标准的东西。现在我希望我的 Cloudfront 分布位于 S3 和 API 网关之前,以便它们位于同一域中,以防止来自我的 SPA 的 CORS 预检请求。

我认为将 cloudfront 转换为 non-caching 模式的最简单方法是转发所有 headers。不幸的是,当我通过设置行为来执行此操作时,我开始收到云端错误 403。我被迫发送缓存控制 headers(来自我的 lambda 'Cache-Control':'no-cache, no-store, must-revalidate')以防止缓存。

通过云端请求 API 网关:

GET - https://dev.b*******e.in/dev/b******e/
:authority:dev.b******e.in
:method:GET
:path:/dev/b******e/
:scheme:https
accept:application/json, text/plain, */*
accept-encoding:gzip, deflate, sdch, br
accept-language:en-US,en;q=0.8
authorization:Bearer eyJmYWNlYm9vayI6eyJhY2Nlc3NfdG9rZW4iOiJFQUFZWGhyd1ZoTnNCQUlmOE5BUWU2ZnpwT2xDd2dUVVpBR1k0VmJZWkFMV0R4ekdYcEttek9NR0paQlNIdzdTeU5oRTloMTY3Nmh3bEZ4d2NpQ1laQnhDQ1IwUWZMWkFmVU1UMTRXOUxME1vWkQiLCJ0b2tlbl90eXBlIjoiYmVhcmVyIiwiZXhwaXJlc19pbiI6IjUxODM5NjcifX0=
cache-control:no-cache
dnt:1
pragma:no-cache
referer:https://dev.b******e.in/b***
user-agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36

Response - Status Code:403 
Response headers:
content-length:551
content-type:text/html
date:Fri, 21 Apr 2017 02:54:23 GMT
server:CloudFront
status:403
via:1.1 3336340a46390eb94ce8a4b00e4863fc.cloudfront.net (CloudFront), 1.1 efe8f585d51dfd5d8d354f74f0385a50.cloudfront.net (CloudFront), 1.1 84760d59a7d324aa7adc2bf9d8f7fd4b.cloudfront.net (CloudFront)
x-amz-cf-id:npw8LPJPvy1Ti_709BvUAHpZOdmOe1wsxm1jO7WdLACyzFESFGtMnQ==
x-cache:Error from cloudfront

响应Body:`

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML><HEAD><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<TITLE>ERROR: The request could not be satisfied</TITLE>
</HEAD><BODY>
<H1>ERROR</H1>
<H2>The request could not be satisfied.</H2>
<HR noshade size="1px">
Bad request.
<BR clear="all">
<HR noshade size="1px">
<PRE>
Generated by cloudfront (CloudFront)
Request ID: 7BVUPh3HiZZGVKLWN9tMEz31gHzq762iPGHHW1fg2I7uNa87205P_Q==
</PRE>
<ADDRESS>
</ADDRESS>
</BODY></HTML>

`

大家是怎么解决这个问题的? 以下是我的分发设置。

我的行为设置(这不起作用):

我的行为设置(有效):

一直让我丧命的是 "Host" header。当您转发所有 header 时,"Host" header 也会从云端转发到 API 网关,这会导致 API 网关失败。检查此 link https://docs.aws.amazon.com/apigateway/api-reference/making-http-requests/ 。看起来目前唯一的解决方案是将您想要的 header 列入白名单,然后从您的 lambda 函数发送 cache-control header。

我知道我的方法有点乱,但对我有利。受您发现 "Host" header 破坏 API GW 的启发,我使用 Lambda@edge 函数修改请求 object 以将主机 header 更改为 API 网关的主机名。 Lambda@edge 是 CloudFront 可以在发送源请求之前触发的 lambda 函数。