我正在尝试记录我自己的WebVitals。示例文档中的简单用例如下所示:
function sendToAnalytics(metric) {
// Replace with whatever serialization method you prefer.
// Note: JSON.stringify will likely include more data than you need.
const body = JSON.stringify(metric);
// Use `navigator.sendBeacon()` if available, falling back to `fetch()`.
(navigator.sendBeacon && navigator.sendBeacon('/analytics', body)) ||
fetch('/analytics', {body, method: 'POST', keepalive: true});
}这一切似乎都很简单。以下是我的实际实现:
function sendToLog(metric) {
// Replace with whatever serialization method you prefer.
// Note: JSON.stringify will likely include more data than you need.
const body = JSON.stringify(metric);
console.log(`Sending body ${body}`);
// Use `navigator.sendBeacon()` if available, falling back to `fetch()`.
// (navigator.sendBeacon && navigator.sendBeacon('https://localho st:9292/api/log', body)) ||
fetch('https://localhost:9292/api/log', {body: body, method: 'POST', headers: { 'Content-Type': 'application/json' }, keepalive: true});
}我不得不修改fetch以包含"body"属性名称,并添加headers以使其正常工作,但现在已经开始工作了。但是,如果我取消对navigator.sendBeacon行的注释,我只会得到身体的{}。
我在后端使用NodeJS和Express。我的出发点是:
const app = express();
app.use(
express.json({
// We need the raw body to verify webhook signatures.
// Let's compute it only when hitting the Stripe webhook endpoint.
verify: function (req, res, buf) {
if (req.originalUrl.startsWith(API_PREFIX + '/webhook')) {
req.rawBody = buf.toString();
}
},
})
);
app.use(cors());
// Expose an endpoint for client logging.
app.post(API_PREFIX + '/log', async (req, res) => {
const message = req.body;
console.log('Got message');
console.dir(message, { depth: null });
logger.info(message);
res.sendStatus(200);
});在这个类似的问题中,公认的答案表明,添加body-parser和app.use(bodyParser.raw())应该能起作用,然后在注释中讨论使用bodyParser.json())。
我试过这两种方法:
import bodyParser from 'body-parser';
...
//app.use(bodyParser.raw());
//app.use(bodyParser.json());
app.use(
express.json({
// We need the raw body to verify webhook signatures.
// Let's compute it only when hitting the Stripe webhook endpoint.
verify: function (req, res, buf) {
if (req.originalUrl.startsWith(API_PREFIX + '/webhook')) {
req.rawBody = buf.toString();
}
},
})
);
app.use(cors());(也就是说,在开头去掉这两行中的任何一行),在所有3种情况下,当使用sendBeacon时,我仍然会得到一个空体。
速递文件说,
express.json是Express中内置的中间件功能.它使用JSON有效负载解析传入的请求,并基于body解析器.在中间件(即req.body)之后,在请求对象上填充包含解析数据的新body对象,如果没有要解析的主体,则填充一个空对象({}),内容类型不匹配,或者出现错误。
所以,我想我不应该需要body-parser,因为express.json就是这样做的;( b)我碰到了这三个条件中的一个(没有人要解析,内容类型没有匹配,或者发生了错误)。假设是这样的,我如何诊断它是哪一个,然后修复它(以fetch回退继续工作的方式)。或者,如果有其他问题,回到原来的问题,我如何使它工作?:)
发布于 2022-07-20 10:07:17
navigator.sendBeacon发送Content-Type: text/plain,而express.json()只在Content-Type: application/json时解析身体。
将express.text()与JSON.parse(req.body)结合使用,或者另外使用:
app.post(API_PREFIX + '/log',
express.json(), express.text(), function(req, res) {
if (typeof req.body === "string") req.body = JSON.parse(req.body);
...
});https://stackoverflow.com/questions/73049624
复制相似问题