为了账号安全,请及时绑定邮箱和手机立即绑定

调用源自浏览器AWS开发工具包时,AWS Lambda设置响应标头

调用源自浏览器AWS开发工具包时,AWS Lambda设置响应标头

跃然一笑 2021-04-27 17:18:44
通过带有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-errorcontent-length: 1242content-type: application/jsondate: Fri, 26 Apr 2019 00:36:35 GMTstatus: 200x-amz-executed-version: $LATESTx-amzn-remapped-content-length: 0x-amzn-requestid: <REDACTED>x-amzn-trace-id: <REDACTED>AWS开发工具包JS浏览器调用代码如下所示:import AWS from 'aws-sdk';AWS.config.region = 'us-east-1'; // RegionAWS.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任何指导,专业知识,思想都将不胜感激!
查看完整描述

2 回答

?
侃侃尔雅

TA贡献1801条经验 获得超16个赞

不,如果没有Lambda服务API(通常是API网关)之前的任何东西,就无法做到这一点

const responseObject实际上是使用API网关指定的格式创建响应的-Lambda服务不对响应进行任何解释。这就是为什么它对响应中的标头没有影响,以及为什么base64保持未翻译的原因-整个结构是特定于API网关的。Lambda只是返回JSON。

如果响应足够小,那么“某物”可能是应用程序负载平衡器,尽管身份验证会有所不同,但它可能与Cognito一起使用可能不太容易,也可能不够容易。它使用与API网关基本相同的响应格式,并且平衡器在将base64返回给浏览器之前对其进行解码。

您还可以使用CloudFront的Lambda @ Edge功能通过HTTP(S)调用Lambda函数,并设置自定义标头并自动解码base64,但是此服务没有内置的Cognito集成,并且与全功能明显不同。 Lambda服务,仅支持Node.js,并在离浏览器最近的AWS区域(而不是在创建该区域的区域)运行Lambda函数,以提高全局性能。Lambda @ Edge还期望使用不同的输出格式,这是一种比API Gateway期望的响应结构更精心设计的设计,因此也不能互换。


查看完整回答
反对 回复 2021-05-13
  • 2 回答
  • 0 关注
  • 214 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信