Express сервер для обслуживающих страниц и конечной точки - PullRequest
0 голосов
/ 30 марта 2020

Я хочу, чтобы веб-сервер Node обслуживал страницы, а также был установлен в качестве конечной точки для прослушивания веб-хуков. Пример для первого взят из Rocket Rides , с соответствующим кодом:

const express = require('express');
// ...
const app = express();
// ...
// CRUD routes for the pilot signup and dashboard
app.use('/pilots', require('./routes/pilots/pilots'));
app.use('/pilots/stripe', require('./routes/pilots/stripe'));
// ...
// Index page for Rocket Rides
app.get('/', (req, res) => {
  res.render('index');
});
// ...
// Start the server on the correct port
const server = app.listen(process.env.PORT || config.port, () => {
  console.log('? Rocket Rides server started:', config.publicDomain);
});

Для второго я использую это руководство со следующим соответствующим кодом :

// Match the raw body to content type application/json
app.post('/webhook', bodyParser.raw({type: 'application/json'}), (request, response) => {
  console.log("called!");
  let event;

  try {
    event = JSON.parse(request.body);
  } catch (err) {
    response.status(400).send(`Webhook Error: ${err.message}`);
  }

  // Handle the event
  switch (event.type) {
    case 'payment_intent.succeeded':
      const paymentIntentSucceeded = event.data.object;
      break;
    case 'payment_method.attached':
      const paymentMethod = event.data.object;
      break;
    // ... handle other event types
    default:
      // Unexpected event type
      return response.status(400).end();
  }

  // Return a response to acknowledge receipt of the event
  response.json({received: true});
});

app.listen(8000, () => console.log('Webhooks running on port 8000'));

В обеих частях сервер не обрабатывает запрос webhook:

Webhooks running on port 8000
POST /webhook 404 590.525 ms - 1415

, и отправитель получает 404.

Когда я комментирую больше всего кода в первой части, запрос webhook обрабатывается правильно:

Webhooks running on port 8000
called!

и отправитель получает 200.

Я полагаю, что один из маршрутов с веб-сервера маскирует маршрут до конечной точки. Я попытался найти один с этой нитью :

app._router.stack.forEach(function(middleware){
    if(middleware.route){ // routes registered directly on the app
        routes.push(middleware.route);
    } else if(middleware.name === 'router'){ // router middleware 
        middleware.handle.stack.forEach(function(handler){
            route = handler.route;
            route && routes.push(route);
        });
    }
});

console.log(routes);

, и единственным релевантным был GET /.

Если я включу код для конечной точки перед код для маршрутизатора, веб-крючок обрабатывается правильно.

Как я могу найти, какой маршрут маскирует конечную точку веб-крюка?

1 Ответ

1 голос
/ 30 марта 2020

Сначала укажите более точные c определения маршрутов, например:

app.use('/pilots/stripe', require('./routes/pilots/stripe'));
app.use('/pilots', require('./routes/pilots/pilots'));

, а более общие определения маршрутов - позже. Это гарантирует, что более специфичные c маршруты не будут сожраны более общими обработчиками.

Имейте в виду, что с app.use() что-то вроде app.use('/pilots') будет соответствовать любому маршруту, начинающемуся с /pilots который будет включать все ваши /pilots/stripe маршруты. Итак, вы хотите убедиться и поставить app.use('/pilots/stripe', ...) перед app.use('/pilots', ...).


Еще одно наблюдение. В вашем обработчике /webhook вам необходимо return после отправки состояния ошибки, чтобы остальная часть вашего обработчика запросов не продолжала работать.

// Match the raw body to content type application/json
app.post('/webhook', bodyParser.raw({type: 'application/json'}), (request, response) => {
  console.log("called!");
  let event;

  try {
    event = JSON.parse(request.body);
  } catch (err) {
    response.status(400).send(`Webhook Error: ${err.message}`);
    return;                         // <=====  Add this
  }
  ....
}

Это похоже на ошибку в актуальная документация по полосам.


Если я добавлю код для конечной точки перед кодом для маршрутизатора, веб-крючок будет обработан правильно.

Я бы предположил, что у вас есть промежуточное ПО bodyparser в другом месте на вашем сервере. Если это промежуточное ПО ДО этого маршрута, то этот маршрут не будет использовать его bodyParser.raw() и получать данные так, как он хочет, и он не будет работать должным образом. Это связано с тем, что какое бы промежуточное программное обеспечение bodyParser ни выполнялось первым, оно читает тело, анализирует его и помещает его туда, где это промежуточное программное обеспечение настроено для его размещения. Как только тело прочитано, оно уходит из потока, поэтому любое другое промежуточное программное обеспечение, которое приходит и также пытается прочитать данные тела из потока, найдет поток пустым.

Итак, этот маршрут должен быть перед любым другим промежуточным программным обеспечением для синтаксического анализа тела, которое может обрабатывать JSON.

Если вы предоставили ссылку на полный код, мы могли бы посмотреть и посмотреть где это происходит.

...