【问题标题】:Returning Dynamic Content-Type via AWS API Gateway and Lambda Function通过 AWS API Gateway 和 Lambda 函数返回动态内容类型
【发布时间】:2018-04-23 05:57:50
【问题描述】:

我想使用 AWS API Gateway 作为代理从 S3 存储桶中获取文件并将它们返回给客户端。我正在使用 Lambda 函数与 S3 通信并通过 AWS API Gateway 将文件发送到客户端。我认为最好的方法是使用“Lambda 代理集成”,以便整个请求无需任何修改即可通过管道传输到 Lambda。但是,如果我这样做,那么我将无法为我的 Lambda 函数的结果响应设置集成响应。所以客户端得到的只是 JSON。

API 网关似乎应该有一种方法来获取 JSON 并将请求转换为客户端的正确响应,但我似乎无法弄清楚如何实现这一点。有很多示例指向手动在 API 网关的响应上设置内容类型,但我需要将内容类型标头设置为任何文件类型。

对于图像和二进制格式,我的 Lambda 函数返回一个 base64 编码字符串,属性 isBase64Encoded 设置为 true。当我转到“二进制支持”部分并将image/* 之类的内容指定为应作为二进制返回的内容类型时,它不起作用。我只有通过将二进制支持内容类型设置为*/*(又名一切)才能成功,这对非二进制内容类型不起作用。

我错过了什么,为什么这看起来如此困难?

【问题讨论】:

    标签: amazon-web-services lambda aws-lambda content-type aws-api-gateway


    【解决方案1】:

    原来 API 网关不是问题所在。我的 Lambda 函数没有返回正确的标头。

    为了处理二进制响应,我发现您需要将 Binary Support 内容类型设置为 */*(又名一切),然后让您的 Lambda 函数返回属性 isBase64Encoded 设置为 true。经过 base64 编码和指示的响应将被解码并以二进制形式提供,而其他请求将按原样返回。

    以下是 Lambda 函数的简单要点,该函数采用给定路径并从 S3 读取文件并通过 API 网关返回:

    /**
     * This is a simple AWS Lambda function that will look for a given file on S3 and return it
     * passing along all of the headers of the S3 file. To make this available via a URL use
     * API Gateway with an AWS Lambda Proxy Integration.
     * 
     * Set the S3_REGION and S3_BUCKET global parameters in AWS Lambda
     * Make sure the Lambda function is passed an object with `{ pathParameters : { proxy: 'path/to/file.jpg' } }` set
     */
    
    var AWS = require('aws-sdk');
    
    exports.handler = function( event, context, callback ) {
        var region = process.env.S3_REGION;
        var bucket = process.env.S3_BUCKET;
        var key = decodeURI( event.pathParameters.proxy );
    
        // Basic server response
        /*
        var response = {
            statusCode: 200,
            headers: {
                'Content-Type': 'text/plain',
            },
            body: "Hello world!",
        };
        callback( null, response );
        */
    
        // Fetch from S3
        var s3 = new AWS.S3( Object.assign({ region: region }) );
        return s3.makeUnauthenticatedRequest(
            'getObject',
            { Bucket: bucket, Key: key },
            function(err, data) {
                if (err) {
                    return err;
                }
    
                var isBase64Encoded = false;
                if ( data.ContentType.indexOf('image/') > -1 ) {
                    isBase64Encoded = true;
                }
    
                var encoding = '';
                if ( isBase64Encoded ) {
                    encoding = 'base64'
                }
                var resp = {
                    statusCode: 200,
                    headers: {
                        'Content-Type': data.ContentType,
                    },
                    body: new Buffer(data.Body).toString(encoding),
                    isBase64Encoded: isBase64Encoded
                };
    
                callback(null, resp);
            }
        );
    };
    

    通过https://gist.github.com/kingkool68/26aa7a3641a3851dc70ce7f44f589350

    【讨论】:

      猜你喜欢
      • 2020-04-24
      • 2017-04-19
      • 1970-01-01
      • 2016-01-27
      • 1970-01-01
      • 2021-07-29
      • 1970-01-01
      • 2015-10-15
      • 2020-10-15
      相关资源
      最近更新 更多