Serverless 应用中使用 CloudFront 遇到的问题及解决方案

在构建 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


纠错反馈