通过带有AWS Lambda代理集成的API Gateway设置响应标头很简单,如下所示:
import zlib from 'zlib';
exports.handler = async (event, context, callback) => {
const body = zlib.gzipSync(JSON.stringify({ data: 'mock' }));
const headers = {};
headers['Content-Type'] = 'application/json';
headers['Content-Encoding'] = 'gzip';
const responseObject = {
statusCode: 200,
headers,
body: body.toString('base64'),
isBase64Encoded: true
};
return callback(null, responseObject);
}
一切都按预期方式以压缩方式返回。因为我们设置了内容编码,所以浏览器解压缩了响应。
问题是,使用AWS开发工具包JS直接从浏览器调用Lambda函数时,如何设置标头?API Gateway是一项服务,该服务实现了先前设置中的标头,而没有在AWS Lambda标头前面放置API Gateway,而是将标头设置为:
access-control-allow-origin: *
access-control-expose-headers: x-amzn-RequestId,x-amzn-ErrorType,x-amzn-ErrorMessage,Date,x-amz-log-result,x-amz-function-error
content-length: 1242
content-type: application/json
date: Fri, 26 Apr 2019 00:36:35 GMT
status: 200
x-amz-executed-version: $LATEST
x-amzn-remapped-content-length: 0
x-amzn-requestid: <REDACTED>
x-amzn-trace-id: <REDACTED>
AWS开发工具包JS浏览器调用代码如下所示:
import AWS from 'aws-sdk';
AWS.config.region = 'us-east-1'; // Region
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: '<SOME IDENTITY>',
});
const AWSLambda = new AWS.Lambda({region: REGION, apiVersion: '2015-03-31'});
const parameters = {
FunctionName : 'MyFunctionName',
InvocationType : 'RequestResponse',
LogType : 'None',
Payload: JSON.stringify({msg: 'hello lambda'})
};
(async () => {
const response = await AWSLambda.invoke(shopParameters).promise();
console.log(response);
})();
返回的响应是上面的响应对象,是带有通用标头的字符串。浏览器不会解压缩压缩的内容,大概是因为未设置内容编码标头。从浏览器调用时,AWS Lambda会将整个Lambda响应对象视为响应,并且不会执行API Gateway发生的任何转换。例如,API网关将选择响应对象结构并将响应对象标头映射到响应,然后再发送给客户端。
没有API Gateway,没有办法设置AWS Lambda标头吗?或者是使用诸如https://github.com/nodeca/pako之类的东西在客户端上手动解压缩gzip内容的唯一选项(叹气)。
不使用API网关的想法来自此处找到的AWS文档,例如避免API网关成本:https : //docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/browser-invoke-lambda -function-example.html
任何指导,专业知识,思想都将不胜感激!
侃侃尔雅
相关分类