通过 POST 发送文件时,AWS lambda 函数 returns HTTP 403
AWS lambda function returns HTTP 403 when sending file via POST
我正在使用无服务器将小型 node/express 应用程序迁移到 lambda 函数。
我的应用程序非常简单。没有身份验证。只有 1 个端点,允许 GET 和 POST。 问题是 GET 有效,但是当我发送 POST 请求发送二进制文件(docx 文件)
时,我收到 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后,创建了一个亚马逊API网关并部署了函数,但是无法使用POST将二进制文件发送到我的应用程序。
这可能是 API 网关的问题,但无法修复。
编辑
第一个响应是正确的,只是 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+}'
我认为您混淆了一些概念:
- 你只有一个功能。我不确定为什么要在
serverless.yml
文件 上定义两个
- 你在一个函数下有很多方法,因为你把所有要表达的东西都委托给处理。
- 如果你想拥有多个功能,每个功能都映射到不同的 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 结果:
并发出 POST 结果:
这正是您所期待的。
我正在使用无服务器将小型 node/express 应用程序迁移到 lambda 函数。
我的应用程序非常简单。没有身份验证。只有 1 个端点,允许 GET 和 POST。 问题是 GET 有效,但是当我发送 POST 请求发送二进制文件(docx 文件)
时,我收到 HTTP 错误 403var 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后,创建了一个亚马逊API网关并部署了函数,但是无法使用POST将二进制文件发送到我的应用程序。
这可能是 API 网关的问题,但无法修复。
编辑
第一个响应是正确的,只是 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+}'
我认为您混淆了一些概念:
- 你只有一个功能。我不确定为什么要在
serverless.yml
文件 上定义两个
- 你在一个函数下有很多方法,因为你把所有要表达的东西都委托给处理。
- 如果你想拥有多个功能,每个功能都映射到不同的 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 结果:
并发出 POST 结果:
这正是您所期待的。