firebase 云函数模拟器中缺少 rawBody
rawBody is missing in firebase cloud functions emulator
https://firebase.google.com/docs/functions/http-events 表示 rawBody
参数应该存在于 req
上。但是,在我的本地模拟器中是undefined
。
我做错了什么?
$ firebase --version
7.8.1
我的客户端 javascript 发布二进制数据的代码:
var buffer = new ArrayBuffer(4);
var view = new DataView(buffer);
function writeUTFBytes(view, offset, string) {
var lng = string.length;
for (var i = 0; i < lng; i++) {
view.setUint8(offset + i, string.charCodeAt(i));
}
}
writeUTFBytes(view, 0, 'RIFF');
var blob = new Blob([view]);
fetch('http://localhost:5001/firebase-project-name/us-central1/endpointName', {
method: 'POST',
body: blob
})
我的 index.js firebase 云函数代码:
const functions = require('firebase-functions');
exports.endpointName = functions.https.onRequest((req, res) => {
res.set('Access-Control-Allow-Origin', 'http://localhost:3000');
console.log(req.rawBody);
console.log(typeof req.rawBody);
res.end();
});
当我 运行 函数时,这是我得到的:
$ firebase emulators:start --only functions
<snip>
i functions: Beginning execution of "endpointName"
>
> undefined
我已经用 HTTP 工具包确认正文实际上是从我的浏览器发送的:
我发现如果我将 content-type 设置为 application/octet-stream 或 audio/wave 那么 rawBody 就会突然出现!
fetch(url, {
method: 'POST',
headers: new Headers({
'Content-Type': 'audio/wav',
}),
body: blob
})
但是!我必须修改我的函数以使 OPTIONS HTTP 请求成功,以便我的浏览器询问是否可以包含 Content-Type header,否则,实际请求从未发送过:
res.set('Access-Control-Allow-Origin', 'http://localhost:3000');
if (req.method === 'OPTIONS') {
// Send response to OPTIONS requests
res.set('Access-Control-Allow-Methods', 'OPTIONS, POST');
res.set('Access-Control-Allow-Headers', 'Content-Type, Content-Length');
res.set('Access-Control-Max-Age', '3600');
return res.status(204).send('');
}
但是,我仍然很好奇为什么没有 content-type header 就没有 rawBody。至少,可能会有一些文档介绍发送二进制数据和使用 rawBody 的端到端示例。
https://firebase.google.com/docs/functions/http-events 表示 rawBody
参数应该存在于 req
上。但是,在我的本地模拟器中是undefined
。
我做错了什么?
$ firebase --version
7.8.1
我的客户端 javascript 发布二进制数据的代码:
var buffer = new ArrayBuffer(4);
var view = new DataView(buffer);
function writeUTFBytes(view, offset, string) {
var lng = string.length;
for (var i = 0; i < lng; i++) {
view.setUint8(offset + i, string.charCodeAt(i));
}
}
writeUTFBytes(view, 0, 'RIFF');
var blob = new Blob([view]);
fetch('http://localhost:5001/firebase-project-name/us-central1/endpointName', {
method: 'POST',
body: blob
})
我的 index.js firebase 云函数代码:
const functions = require('firebase-functions');
exports.endpointName = functions.https.onRequest((req, res) => {
res.set('Access-Control-Allow-Origin', 'http://localhost:3000');
console.log(req.rawBody);
console.log(typeof req.rawBody);
res.end();
});
当我 运行 函数时,这是我得到的:
$ firebase emulators:start --only functions
<snip>
i functions: Beginning execution of "endpointName"
>
> undefined
我已经用 HTTP 工具包确认正文实际上是从我的浏览器发送的:
我发现如果我将 content-type 设置为 application/octet-stream 或 audio/wave 那么 rawBody 就会突然出现!
fetch(url, {
method: 'POST',
headers: new Headers({
'Content-Type': 'audio/wav',
}),
body: blob
})
但是!我必须修改我的函数以使 OPTIONS HTTP 请求成功,以便我的浏览器询问是否可以包含 Content-Type header,否则,实际请求从未发送过:
res.set('Access-Control-Allow-Origin', 'http://localhost:3000');
if (req.method === 'OPTIONS') {
// Send response to OPTIONS requests
res.set('Access-Control-Allow-Methods', 'OPTIONS, POST');
res.set('Access-Control-Allow-Headers', 'Content-Type, Content-Length');
res.set('Access-Control-Max-Age', '3600');
return res.status(204).send('');
}
但是,我仍然很好奇为什么没有 content-type header 就没有 rawBody。至少,可能会有一些文档介绍发送二进制数据和使用 rawBody 的端到端示例。