在构建 Serverless 应用的过程中,使用 AWS 的 CloudFront 进行 CDN 加速是很常见的需求。然而,在使用 CloudFront 时,可能会遇到一些问题,本文将介绍一些常见的问题及解决方案。
问题一:保留 URL 中的查询字符串
有时候,我们需要保留 URL 中的查询字符串,比如在应用中需要根据查询参数进行操作。然而,在使用 CloudFront 时,默认情况下,查询字符串会被忽略,导致应用不可用。
解决方案:在 CloudFront 的 Distribution 菜单中,选择 Behaviors 选项卡,然后点击 Create Behavior。在 Create Behavior 的页面中,选择 Query String Forwarding and Caching,将 Forward query strings 选项设置为 "All"。
示例代码:
{ "DistributionConfig": { "Origins": [{ "Id": "origin-1", "DomainName": "example.com.s3.amazonaws.com.s3.amazon.com", "S3OriginConfig": {} }], "DefaultCacheBehavior": { "TargetOriginId": "origin-1", "ViewerProtocolPolicy": "redirect-to-https", "ForwardedValues": { "QueryString": true, "Cookies": { "Forward": "all" } }, "AllowedMethods": [ "GET", "HEAD", "OPTIONS" ], "CachedMethods": [ "GET", "HEAD", "OPTIONS" ], "MinTTL": 0 }, "Enabled": true, "Comment": "Test CloudFront distribution", "PriceClass": "PriceClass_All", "DefaultRootObject": "index.html", "WebACLId": "string", "HttpVersion": "http2", "IsIPV6Enabled": true } }
问题二:保持浏览器缓存
在使用 CDN 进行加速时,为了优化用户体验,我们通常会想要将静态资源缓存在用户的本地浏览器中,这样可以减少对服务器的请求,提高加载速度。然而,在使用 CloudFront 时,如果我们对静态资源进行了版本更新,缓存在浏览器中的资源可能就无法及时更新。
解决方案:在 CloudFront 的 Distribution 菜单中,选择 Behaviors 选项卡,然后点击 Create Behavior。在 Create Behavior 的页面中,选择 Cache Based on Selected Request Headers,并将 Include Headers 选项中的 If-Modified-Since,If-None-Match,Access-Control-Request-Headers 和 Access-Control-Request-Method 均设置为 "Yes"。这样,CloudFront 就会在某些情况下返回 304 Not Modified 响应码,告诉浏览器使用本地缓存。
示例代码:
{ "DistributionConfig": { "Origins": [{ "Id": "origin-1", "DomainName": "example.com.s3.amazonaws.com.s3.amazon.com", "S3OriginConfig": {} }], "DefaultCacheBehavior": { "TargetOriginId": "origin-1", "ViewerProtocolPolicy": "redirect-to-https", "ForwardedValues": { "QueryString": true, "Cookies": { "Forward": "all" }, "Headers": [ "Access-Control-Request-Headers", "Access-Control-Request-Method", "If-Modified-Since", "If-None-Match" ] }, "AllowedMethods": [ "GET", "HEAD", "OPTIONS" ], "CachedMethods": [ "GET", "HEAD", "OPTIONS" ], "MinTTL": 0, "MaxTTL": 31536000, "DefaultTTL": 86400, "Compress": true, "SmoothStreaming": false, "LambdaFunctionAssociations": [] }, "Enabled": true, "Comment": "Test CloudFront distribution", "PriceClass": "PriceClass_All", "DefaultRootObject": "index.html", "WebACLId": "string", "HttpVersion": "http2", "IsIPV6Enabled": true } }
问题三:从 CloudFront 访问特定存储桶
有时候,我们需要让 CloudFront 从特定的存储桶中获取资源,而不是从所有存储桶中获取。这时,我们需要将存储桶配置为 CloudFront 访问的专用存储桶。
解决方案:在存储桶页面的 Permissions 选项卡中,点击 Bucket Policy,然后编辑 Bucket Policy,创建一个只允许特定 IP 地址访问的 policy。在 CloudFront 的 Distribution 菜单中,选择 Origins 选项卡,然后点击 Create Origin。在 Create Origin 页面的 Domain Name 输入框中输入存储桶的名称和 Region,然后将 Restrict Bucket Access 选项设置为 "Yes"。在 Restrict Viewer Access (Use Signed URLs or Signed Cookies) 的选项中,选择 "No".
示例代码:
{ "DistributionConfig": { "Origins": [{ "Id": "origin-1", "DomainName": "example.com.s3.amazonaws.com.s3.amazon.com", "S3OriginConfig": {}, "CustomHeaders": { "X-Custom-Header": "My custom value" }, "OriginPath": "/subdirectory", "RestrictBucketAccess": true, "S3OriginConfig": { "OriginAccessIdentity": "origin-access-identity/cloudfront/example" } }], "DefaultCacheBehavior": { "TargetOriginId": "origin-1", "ViewerProtocolPolicy": "redirect-to-https", "ForwardedValues": { "QueryString": true, "Cookies": { "Forward": "all" }, "Headers": [ "Access-Control-Request-Headers", "Access-Control-Request-Method", "If-Modified-Since", "If-None-Match" ] }, "AllowedMethods": [ "GET", "HEAD", "OPTIONS" ], "CachedMethods": [ "GET", "HEAD", "OPTIONS" ], "MinTTL": 0, "MaxTTL": 31536000, "DefaultTTL": 86400, "Compress": true, "SmoothStreaming": false, "LambdaFunctionAssociations": [] }, "Enabled": true, "Comment": "Test CloudFront distribution", "PriceClass": "PriceClass_All", "DefaultRootObject": "index.html", "WebACLId": "string", "HttpVersion": "http2", "IsIPV6Enabled": true } }
总结
在构建 Serverless 应用时,使用 CloudFront 进行 CDN 加速是很常见的需求。然而,在使用 CloudFront 时可能会遇到一些问题,本文介绍了保留 URL 中的查询字符串,保持浏览器缓存和从 CloudFront 访问特定存储桶等常见问题的解决方案。希望这些解决方案对您有所帮助。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/659f842dadd4f0e0ff81a248