如何使用自定义域将Cloudfront转发到HTTP API

问题描述

我正在/路径下使用s3和cloudfront服务静态网站。

我想通过HTTP API提供/api/*

我的静态网站已使用Cloudfront正确配置。而且我还配置了custom domain to HTTP api with cdk

但是当我尝试访问我的http API时,我得到404 not found响应。基本上,Cloudfront不会将我的/api/*请求转发到HTTP API。

这是我的Cloudfront CDK代码

const distribution = new CloudFrontWebdistribution(this,'CloudfrontWebdistribution',{
      httpVersion: HttpVersion.HTTP2,priceClass: PriceClass.PRICE_CLASS_ALL,viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,originConfigs: [
        {
          s3OriginSource: {
            s3BucketSource: bucket,originAccessIdentity
          },behaviors: [{
              isDefaultBehavior: true,defaultTtl: Duration.hours(1)
            }]
        },{
          customOriginSource: {
            domainName: website_domain
          },behaviors: [{
            pathPattern: '/api/*',isDefaultBehavior: false,allowedMethods: CloudFrontAllowedMethods.ALL,defaultTtl: Duration.seconds(0),minTtl: Duration.seconds(0),maxTtl: Duration.seconds(0),forwardedValues: {
              queryString: true,cookies: {
                forward: 'all'
              }
            }
          }]
        }
      ],errorConfigurations: [
        {
          errorCode: 404,responseCode: 404,responsePagePath: '/404.html'
        }
      ],viewerCertificate: ViewerCertificate.fromAcmCertificate(certificate,{
        aliases: [website_domain],securityPolicy: SecurityPolicyProtocol.TLS_V1_2_2018
      })
    })

这不是必需的,但我还要提供我的HTTP API自定义域CDK代码

    const certificate = Certificate.fromCertificateArn(this,'ssl_cert',certArn)
    
    const domain = new DomainName(this,'domain',{
      domainName: website_domain,certificate
    }) 

    const api = new HttpApi(this,'endpoint',{
      defaultDomainMapping: {
        domainName: domain,mappingKey: 'api'
      },corsPreflight: {
        allowCredentials: true,allowHeaders: ['Content-Type'],allowMethods: [HttpMethod.GET,HttpMethod.POST,HttpMethod.OPTIONS,HttpMethod.HEAD],allowOrigins: [
          "https://cdn.ampproject.org","https://www.bing-amp.com"
        ]
      },apiName: 'myAPI'
    })

解决方法

我在代码段中没有看到您对HttpApi的路由定义,但是我怀疑问题在于它们不是以/api开头。

CloudFront行为中的pathPattern仅用于匹配URL并路由到适当的来源。但是CloudFront不会将其从转发到原点的路径中删除。

我知道有两种解决方案

  • 在所有路线的前面添加/api路径段
  • 在调用原点之前,使用lambda @ edge删除路径段。

对于第二个选项,请点击此处接受的答案:Multiple Cloudfront Origins with Behavior Path Redirection