AWS API 网关 + Lambda:图标问题

AWS API Gateway + Lambda: favicon issue

我在 AWS Lambda (ASP.NET Core 3.1) 上有一个微服务 运行 并使用带有自定义域的 API 网关发布。

运行 在本地,一切正常,站点正常,图像已加载,图标也已加载。

已部署到 Lambda+API,网站正常运行,图像已加载(PNG、JPG),脚本已加载,但是 favicon.ico 未加载。 Returns 图片无效。 PNG、JPG、CSS、JS 或任何其他静态内容没有特殊配置,开箱即用。

网站图标有什么问题吗?

以下解决方案对我有用。

与其使用 API 网关服务 favicon.ico,不如将其上传到 S3 并使其成为 public 对象。从 S3 控制台获取此对象的 HTTPS url。然后在您的 Lambda 函数中,重定向到它。

在我的例子中,这是一个 AWS Chalice (Python) 应用程序,因此路由逻辑实现如下:

@app.route('/favicon.ico')
def favicon(): 
  return Response(body='', headers={'Location': 'https://s3.amazonaws.com/YOUR_BUCKET_NAME/favicon.ico'}, status_code=301)

虽然不是绝对必要,但您也可以在 HTML 中包含标记以指示网站图标的位置,例如:

<link rel="icon" type="image/x-icon" href="/favicon.ico" />

以下解决方案允许我通过 API 网关 + Lambda 提供 favicon,并创建或使用其他资源。 API 使用的是 REST API 而我在我的 lambda 上 运行 的应用程序是 Plotly Dash 应用程序。

为了部署我的 API 我在 template.yaml 中设置了以下内容(仅供参考:以下不是完整的模板)

Resources:
  DashApi:
    Type: AWS::Serverless::Api
    Properties:
      BinaryMediaTypes:
        - "image/*"
  
  MyLambdaFunction:
    Type: AWS::Serverless::Function
    Properties:
        Events:
          DashEndpoint:
            Type: Api
            Properties:
              Path: /{proxy+}
              Method: ANY
              RestApiId:
                Ref: DashApi

这里重要的是设置 BinaryMediaTypes 因为这将告诉您 API 哪些数据作为二进制数据传递,哪些作为 utf-8 编码数据传递。在此示例中,我将所有图像类型设置为二进制,但您也可以使用 "*/*" 将所有内容类型设置为二进制,或者仅列出特定图像类型。

也许对于许多网络服务器来说这已经足够了,但是对于 Plotly Dash 应用程序您必须设置另一个设置。对于那些应用程序,我使用 aws-wsgi package 来处理响应。默认情况下,此库中的调用会将所有内容解码为 utf-8,除非另有明确说明。为此,您必须设置 base64_content_types 输入参数( 字符串列表 )。

Note: the asterix wildcard doesn't work here since awsgi does a literal comparison of Content-Type with all entries in the list

def lambda_handler(event, context):
    base64_content_types = ['image/vnd.microsoft.icon', 'image/x-icon']
    return awsgi.response(app.server, event, context, base64_content_types )

设置好这两个设置后,我就可以加载图标了。

我希望这些信息仍然对某些人有所帮助。我还是把它列在这里了,因为在网上几乎找不到不使用 S3 存储桶解决这个问题的资料。