Я пытаюсь настроить дистрибутив CloudFront, который кэширует все ресурсы, кроме HTML-файлов, при этом принудительно применяя чистые URL-адреса с помощью функции CloudFront. Однако похоже, что моя текущая установка также кэширует файлы HTML. Хотелось бы понять почему и как это исправить.
Я определил два поведения кэша в своем дистрибутиве: одно с шаблоном пути *.html
и политикой Managed-CachingDisabled
, а другое поведение по умолчанию (*
) с политикой Managed-CachingOptimized
.
Вот как выглядит поведение в моем шаблоне CloudFromation:
DefaultCacheBehavior:
TargetOriginId: s3origin
CachePolicyId: 658327ea-f89d-4fab-a63d-7e88639e58f6 # CachingOptimized
ViewerProtocolPolicy: redirect-to-https
AllowedMethods: [GET, HEAD, OPTIONS]
CachedMethods: [GET, HEAD, OPTIONS]
Compress: true
FunctionAssociations:
- EventType: viewer-request
FunctionARN: !GetAtt RedirectFunction.Outputs.FunctionArn
CacheBehaviors:
- PathPattern: '*.html'
TargetOriginId: s3origin
CachePolicyId: 4135ea2d-6df8-44a3-9df3-4b5a84be39ad # CachingDisabled
ViewerProtocolPolicy: redirect-to-https
AllowedMethods: [GET, HEAD, OPTIONS]
CachedMethods: [GET, HEAD, OPTIONS]
Compress: true
FunctionAssociations:
- EventType: viewer-request
FunctionARN: !GetAtt RedirectFunction.Outputs.FunctionArn
Оба поведения также имеют функцию CloudFront, связанную с ними на этапе viewer-request
, которая обеспечивает «чистые URL-адреса», загружая файл «index.html» из любого пути, заканчивающегося косой чертой, и перенаправляя любые «нечистые URL-адреса» на этот путь. Эта функция выглядит так:
var indexDocument = 'index.html';
function redirect(uri) {
return {
statusCode: 301,
statusDescription: 'Moved Permanently',
headers: { location: { value: uri } },
};
}
function handler(event) {
var request = event.request;
var uri = request.uri || '/';
if (uri.endsWith('/')) {
// add index document and return properly-formatted requests
request.uri = uri + indexDocument;
return request;
}
if (uri.endsWith('/' + indexDocument)) {
// trim index document
return redirect(uri.slice(0, -indexDocument.length));
}
if (!request.uri.includes('.')) {
// add trailing slash
return redirect(uri + '/');
}
return request;
}
Мне не удалось найти никакой документации по этому вопросу, но я должен предположить, что CloudFront выбирает поведение кэша на основе первоначального запроса пользователя, который представляет собой чистый URL-адрес без расширения .html
, а не исходный запрос, возвращенный моим Функция CloudFront, которая добавляет в запрос документ index.html
.
Если это так, как я могу указать другое поведение кэша для файлов HTML при использовании чистых перенаправлений URL? Если это не так, почему мой дистрибутив может кэшировать HTML-файлы?
Я понял, что путаю кеши CloudFront (кеширование файлов в периферийных местоположениях) с кешами клиентов, управляемыми HTTP-заголовком Cache-Control
. Единственный способ установить последнее — изменить заголовки объектов S3. Это то, чего я на самом деле хотел.
Также можно исключить HTML-файлы из пограничных кэшей, при этом применяя чистые URL-адреса со следующими характеристиками:
DefaultCacheBehavior:
TargetOriginId: s3origin
CachePolicyId: 4135ea2d-6df8-44a3-9df3-4b5a84be39ad # CachingDisabled
ViewerProtocolPolicy: redirect-to-https
CacheBehaviors:
- PathPattern: '*.html'
TargetOriginId: s3origin
CachePolicyId: 4135ea2d-6df8-44a3-9df3-4b5a84be39ad # CachingDisabled
ViewerProtocolPolicy: redirect-to-https
- PathPattern: '*.*'
TargetOriginId: s3origin
CachePolicyId: 658327ea-f89d-4fab-a63d-7e88639e58f6 # CachingOptimized
ViewerProtocolPolicy: redirect-to-https
Но после осознания своей ошибки я не уверен, что это когда-либо полезно/желательно.