我已经运行了Azure Function,它是作为Expressjs应用程序编写的。 我有简单的路线来测试
// Test get
router.get('/test', (req, res) => {
return res.status(200).send({ result: req.query });
});
// Test post
router.post('/test', (req, res) => {
return res.status(200).send({ result: req.body });
});
应用配置如下
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cors());
我尝试POST /test
请求。
使用Content-Type: application/javascript
时效果很好
使用Content-Type: application/json
它会调用函数,但不执行任何操作,并返回超时。
GET /test
路线没有问题
在本地运行没有问题。
需要帮助才能理解为什么Azure函数调用对于使用Content-Type:application / json的POST请求无法正常工作。谢谢
答案 0 :(得分:2)
使用:
app.use(bodyParser.json({ type: 'application/*+json' }));
允许自定义json类型
答案 1 :(得分:2)
深入了解Azure功能和正文解析器的工作原理,我找出了问题的根源。
小心使用request
对象
在常规expressjs app中,我们有request
个对象,它实际上是Stream对象的实例,所有传入的数据都通过此流式传输。
因此,我们有原始数据,我们需要正确解析它。 bodyParser
中间件有几种方法可以根据流的类型(内容类型)从流中解析这些数据。
例如,bodyParser.json()
方法尝试使用application/json
内容类型解析JSON格式的数据。一旦此函数解析了数据req.body
,就会使用JSON对象来实现。
Azure功能不支持流式传输
这就是一切都破了:)是的,它不支持流式传输。而且由于这是真实的数据被接受的方式不同。所以request
对象不再是Stream对象。并且传入的数据已经满足req.body
。对于application/json
,它包含JSON对象,对于其他内容类型,它包含需要解析的原始数据。例如,我可以共享我的简单中间件代码,用于解析类型为x-www-form-urlencoded
的数据。
'use strict';
// https://github.com/sindresorhus/query-string
const queryString = require('query-string');
/**
* Azure body parser
*/
function azureBodyParser() {
return function(req, res, next) {
// x-www-form-urlencoded
if (req.headers['content-type'] === 'application/x-www-form-urlencoded') {
req.body = queryString.parse(req.body, { arrayFormat: 'bracket' });
}
next();
};
}
module.exports = azureBodyParser;
然后像这样使用它
const app = require('express')();
const azureBodyParser = require('./middlewares/azureBodyParser');
// ...
app.use(azureBodyParser());
您可以更改它并为其他内容类型添加更多处理程序 此外,我们需要提供一些条件,无论我们是在服务器上运行我们的应用程序还是作为Azure功能,例如,可以使用ENV变量。这是你的家庭任务:)
问题
由于Azure功能不支持流式传输,bodyParser.json()
尝试从流中获取数据,这是app卡住的一个点。结果,函数执行以超时结束。
希望对所有与Azure斗争的人都有所帮助...祝你好运:)。