首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Express中解析sendBeacon数据

在Express中解析sendBeacon数据
EN

Stack Overflow用户
提问于 2022-07-20 10:02:53
回答 1查看 94关注 0票数 0

我正在尝试记录我自己的WebVitals。示例文档中的简单用例如下所示:

代码语言:javascript
复制
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});
}

这一切似乎都很简单。以下是我的实际实现:

代码语言:javascript
复制
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。我的出发点是:

代码语言:javascript
复制
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-parserapp.use(bodyParser.raw())应该能起作用,然后在注释中讨论使用bodyParser.json())

我试过这两种方法:

代码语言:javascript
复制
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回退继续工作的方式)。或者,如果有其他问题,回到原来的问题,我如何使它工作?:)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-20 10:07:17

navigator.sendBeacon发送Content-Type: text/plain,而express.json()只在Content-Type: application/json时解析身体。

express.text()JSON.parse(req.body)结合使用,或者另外使用:

代码语言:javascript
复制
app.post(API_PREFIX + '/log',
  express.json(), express.text(), function(req, res) {
  if (typeof req.body === "string") req.body = JSON.parse(req.body);
  ...
});
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73049624

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档