通过POST发送文件时,AWS Lambda函数返回HTTP 403

时间:2019-05-10 12:12:26

标签: amazon-web-services express aws-lambda aws-serverless

我正在使用无服务器将小型节点/ express应用程序迁移到lambda函数。

我的应用程序非常简单。没有身份验证。仅1个端点,允许GET和POST。 问题是GET可以工作,但是当我发送发送二进制文件(docx文件)的POST请求时出现HTTP错误403

var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(express.static(path.join(__dirname, 'public')));


/* GET home page. */
app.get('/', function (req, res, next) {
    res.render('index', {title: 'Whatever'});
});

/* POST receive file */
app.post('/', function (req, res, next) {
    // Simplified to the minimum
    return res.json({'msg': 'ok'});   
});

module.exports.handler = serverless(app);

我的serverless.yml文件看起来像这样

service: my_service

provider:
  name: aws
  runtime: nodejs8.10
  stage: dev
  region: eu-west-3

functions:
  app:
    handler: app.handler
    events:
      - http: GET /
      - http: 'ANY {proxy+}'
  post:
    handler: app.handler
    events:
      - http:
          path: /
          method: post
          cors: true

运行 sls deploy 后,将创建一个Amazon API Gateway并部署该功能,但是无法使用POST将二进制文件发送到我的应用程序。

这可能是API Gateway的问题,但无法解决。

编辑

第一个响应是正确的响应,在serverless.yml文件中只做了很小的更改。这是正确的:

service: my-service

provider:
  name: aws
  runtime: nodejs8.10
  stage: dev
  region: eu-west-3

functions:
  app:
    handler: app.handler
    events:
      - http: GET /
      - http: POST /
      - http: 'ANY {proxy+}'

1 个答案:

答案 0 :(得分:1)

我认为您正在混淆一些概念:

  • 您只有一个功能。我不确定为什么要在serverless.yml文件中定义两个
  • 在ONE函数下您有许多方法,因为您要委派要表达的所有内容以进行处理。
  • 如果您想拥有多种功能,每个功能都映射到不同的HTTP方法,那么您就无需使用Express
  • 您在/下声明了PROXY,ANY,GET和POST(尽管不确定,我认为这是问题的根源,因为API网关在路由中丢失了)。如果您使用的是Express,则不需要它,因为您需要代理每个呼叫。

话虽如此,您应该相应地修改serverless.yml文件:

service: my-service

provider:
  name: aws
  runtime: nodejs8.10
  stage: dev
  region: eu-west-3

functions:
  app:
    handler: app.handler
    events:
      - http: ANY /
      - http: 'ANY {proxy+}'

我已经稍微更改了您的app.js文件,但这只是为了让我更清楚一点,但是您始终可以使用它与您的文件进行比较:

const serverless = require('serverless-http');
const express = require('express')
const app = express()
const bodyParser = require('body-parser');

app.use(bodyParser.json({ strict: false }));

/* GET home page. */
app.get('/', function (req, res, next) {
    res.json({title: 'Whatever'});
});

/* POST receive file */
app.post('/', function (req, res, next) {
    // Simplified to the minimum
    return res.json({'msg': 'ok'});   
});

module.exports.handler = serverless(app);

如果现在使用sls deploy进行部署,则将能够成功执行这两种方法。

我为您运行了两个示例。

发出GET结果:

enter image description here

发出POST会导致:

enter image description here

这正是您所期望的。