Статус HTTP 400 при запросе службы js другого узла

#node.js #typescript #http #server #microservices

#node.js #машинописный текст #http #сервер #микросервисы

Вопрос:

У меня есть две совершенно отдельные службы, Book и они Review написаны TypeScript , у них есть Database свои собственные.

Book Служба запущена на службе, на которой запущена служба localhost:3001 Review localhost:3000

Проблема в том, что когда я пытаюсь запросить reviews каждый book из моих Book сервисов, он показывает эту ошибку неправильного запроса,

 status: 400
headers: connection=close
  

Приведенный ниже код вызывает api Review службу of. На данный момент я просто пытаюсь получить тело.

 public async getAllBooks(req: Request, res: Response) {
       
        await database.query("Select * from books", {
            type: sequelize.QueryTypes.SELECT,
            model: Book,
            mapToModel: true
        })
        .then(async (books) => {
            res.status(200).json(books);
            for(let i=0; i<books.length; i  ) {
                var options = {
                    host: 'localhost',
                    port: 3000,
                    path: `/getReviewByBookId/${books[i].id}`,
                    method: 'GET'
                  };
                  
                  var req = request(options, function(res) {
                    console.log('status: '   res.statusCode);
                    console.log('headers: '   stringify(res.headers));
                    res.setEncoding('utf8');
                    res.on('data', function (chunk) {
                      console.log('BODY: '   chunk);
                    });
                  });
                  
                  req.on('error', function(e) {
                    console.log('problem with request: '   e.message);
                  });
                  
                  req.write('datan');
                  req.write('datan');
                  req.end();
            }
        })
        .catch((error) => {
            console.log(error);
        });
    }
  

Функция, которая получает этот запрос в Review службе, приведена ниже,

 public async getReviewByBookId(req: Request, res: Response) {
        const bookId: number | string = req.params.id;

        await database.query(`Select * from reviews where bookId=${bookId}`, {
            type: sequelize.QueryTypes.SELECT,
            model: Review,
            mapToModel: true
        })
        .then((reviews) => {
            console.log(reviews);
            res.status(200).json({reviews: reviews});
        })
        .catch((error) => {
            console.log(error);
        });
    }
  

Я выяснил, что запрос от Book службы достигает Review службы и вышеупомянутой функции, потому что вышеупомянутая функция печатает все отзывы в console том, что она получила в соответствии с bookId тем, что она получила от запроса Book службы. Но Review служба не возвращает этот результат.

Самое главное, что обе службы работают отлично, когда я тестирую с помощью Postman

Я проверял снова и снова, не поврежден ли uri запроса, поскольку это может вызвать такую ошибку в соответствии с определениями кода состояния HTTP. Но, похоже, все в порядке, поскольку Review служба извлекает данные в соответствии с этим запросом.

Также я включил cors в своей Review службе. Разрешены все HTTP OPTIONS .

Я использую 64-разрядную машину Kali Linux.

Некоторая подсказка означала бы большую помощь. Спасибо за ваше время.

Комментарии:

1. работают ли прямые запросы с использованием postman / similar?

2. Да, они работают отлично.

3. Чтобы было ясно, этот запрос работает с postman, но когда вы пытаетесь сказать, что браузер не работает?

4. На самом деле, когда я запускаю из браузера, он просто показывает книги, но не обзор, который он также должен показывать. И я поместил console.log() в свою книгу сервисную функцию, указанную выше, чтобы проверить, возвращает ли запрос какой-либо ответ вообще … этот ответ всегда показывает код состояния 400… итак, в целом я вижу, что моя служба book ничего не возвращает из службы просмотра …. кроме того, что обе службы работают как из браузера, так и из postman …. проблема возникает, когда я пытаюсь подключить службу book для запроса службы просмотра. И спасибо за ваш комментарий 🙂

Ответ №1:

В приведенном выше коде вы отправляете тело с запросом GET:

 var options = {
    host: 'localhost',
    port: 3000,
    path: `/getReviewByBookId/${books[i].id}`,
    method: 'GET' // <-- It's a GET request
};

var req = request(options, function(res) { ... });


req.write('datan'); // <-- This writes a request body
req.write('datan'); // <--
req.end();
  

Обычно вам не разрешается это делать. Чтобы процитировать RFC:

Полезная нагрузка в сообщении запроса GET не имеет определенной семантики; отправка тела полезной нагрузки в запросе GET может привести к тому, что некоторые существующие реализации отклонят запрос.

Из приведенного здесь кода трудно быть уверенным, но, вероятно, в этом проблема. Сервер получает запрос, начинает его обработку (запуск вашей функции), а затем сервер получает дополнительные неожиданные данные, поэтому отправляет 400 и закрывает соединение.

Вам явно не нужны эти данные, поэтому вам следует просто удалить эти строки. Если вам нужно отправить некоторые данные с этим запросом, вам нужно либо включить их в заголовки / URL запроса, либо изменить запрос на POST / PUT / etc, чтобы вы могли включить тело запроса.

(Я вижу, что прошло некоторое время с тех пор, как вы опубликовали это сейчас, но, надеюсь, этот ответ полезен для других с той же проблемой!)