Webhooks 的 NodeJS 监听器返回空主体

2 webhooks node.js express

我已经这样做了大约两天,准备拔掉我的头发。

我有一个系统,可以触发我需要捕获和解析的简单 Webhooks。我创建了一个非常简单的 Nodejs 监听器,并运行 Ngrok 来创建公共地址。我收到一个请求,但无论我做什么,主体都是空的。与内容类型或 app.use(bodyParser.urlencoded()) 无关。

主体仍然返回为 {}

'use strict'

const express = require('express')
const bodyParser = require('body-parser')

// Create a new instance of express
const app = express()

// Tell express to use the body-parser middleware and to not parse extended bodies
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: false }))

// Route that receives a POST request to /sms
app.post('/', function (req, res) {
    console.log(req);
  const body = req.body
  console.log("body")
  console.log(body);
  res.set('Content-Type', 'text/plain')
  res.send(`You sent: ${body} to Express`)
})


// Tell our app to listen on port 4545
app.listen(4545, function (err) {
  if (err) {
    throw err
  }

  console.log('Server started on port 4545')
})
Run Code Online (Sandbox Code Playgroud)

但是,如果我将地址设置为https://webhook.sitehttps://pipedream.com,那么正文确实会发布。我尝试过内容类型、urlencode 的组合,甚至认为它是 gzip 或其他东西,甚至部署在 Azure VM 和其他虚拟机上。没有什么。

但是当我将地址设置为 webhooks 或 Pipedream 时,数据显示没有问题。

经过一些评论后,我想添加 console.log(req) 的结果(部分结果):

complete: false,
    headers: {
      connection: 'Keep-Alive',
      'accept-encoding': 'gzip',
      host: 'localhost:4646',
      'max-forwards': '10',
      'user-agent': 'Go-http-client/2.0',
      'content-length': '339'
    },
    rawHeaders: [
      'Connection',
      'Keep-Alive',
      'Accept-Encoding',
      'gzip',
      'Host',
      'localhost:4646',
      'Max-Forwards',
      '10',
      'User-Agent',
      'Go-http-client/2.0',
      'X-Original-URL',
      '/',
      'Content-Length',
      '339'
    ],
    trailers: {},
    rawTrailers: [],
    aborted: false,
    upgrade: false,
    url: '/',
    method: 'POST',
    statusCode: null,
    statusMessage: null,
    client: Socket {
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: null,
      _readableState: [ReadableState],
      readable: true,
      _events: [Object: null prototype],
      _eventsCount: 8,
      _maxListeners: undefined,
      _writableState: [WritableState],
      writable: true,
      allowHalfOpen: true,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: [Server],
      _server: [Server],
      timeout: 120000,
      parser: [HTTPParser],
      on: [Function: socketListenerWrap],
      addListener: [Function: socketListenerWrap],
      prependListener: [Function: socketListenerWrap],
      _paused: false,
      _httpMessage: [Circular],
      [Symbol(asyncId)]: 115,
      [Symbol(kHandle)]: [TCP],
      [Symbol(kSetNoDelay)]: false,
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: Timeout {
        _idleTimeout: 120000,
        _idlePrev: [TimersList],
        _idleNext: [Timeout],
        _idleStart: 6602,
        _onTimeout: [Function: bound ],
        _timerArgs: undefined,
        _repeat: null,
        _destroyed: false,
        [Symbol(refed)]: false,
        [Symbol(asyncId)]: 116,
        [Symbol(triggerId)]: 115
      },
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(kCapture)]: false,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0
    },
    _consuming: false,
    _dumped: false,
    next: [Function: next],
    baseUrl: '',
    originalUrl: '/',
    _parsedUrl: Url {
      protocol: null,
      slashes: null,
      auth: null,
      host: null,
      port: null,
      hostname: null,
      hash: null,
      search: null,
      query: null,
      pathname: '/',
      path: '/',
      href: '/',
      _raw: '/'
    },
    params: {},
    query: {},
    res: [Circular],
    body: {},
    route: Route { path: '/', stack: [Array], methods: [Object] },
    [Symbol(kCapture)]: false
  },
  locals: [Object: null prototype] {},
  [Symbol(kCapture)]: false,
  [Symbol(kNeedDrain)]: false,
  [Symbol(corked)]: 0,
  [Symbol(kOutHeaders)]: [Object: null prototype] {
    'x-powered-by': [ 'X-Powered-By', 'Express' ]
  }
}

Run Code Online (Sandbox Code Playgroud)

console.log(req) 时可以看到body为空

任何人都可以送我走上正确的道路来解决这个问题吗?

非常感激。

小智 5

因此,对于其他遇到类似问题的人来说,这就是我要解决的问题:

我必须将内容类型注入标题中,然后中提琴正文开始出现:

var customParser = bodyParser.json({type: function(req) {
    if (req.headers['content-type'] === ""){
        return req.headers['content-type'] = 'application/json';
    }
    else if (typeof req.headers['content-type'] === 'undefined'){
        return req.headers['content-type'] = 'application/json';
    }else{
        return req.headers['content-type'] = 'application/json';
    }
}});


app.use(bodyParser.json({
  limit: '50mb',
  extended: true
})); // support encoded bodies

app.use(bodyParser.urlencoded({
  limit: '50mb',
  extended: true
})); // support encoded bodies


app.post("/hook", customParser, (req, res) => {
    //console.log(req);
    //const fs = require('fs');
    console.log("Events req.body", req.body) // Call your action on the request here

    res.status(200).end()
  })

Run Code Online (Sandbox Code Playgroud)

那对我来说是这样的。

谢谢