node.js - HTTP-status 400 vid begäran till en annan node.js-tjänst
Jag har två helt separata tjänster Book och Review skrivna i TypeScript, de har egna separata Database.
Tjänsten Book körs på localhost:3001 Tjänsten Review körs på localhost:3000
Problemet är när jag försöker begära recensioner för varje bok från min Bok-tjänst visar den detta fel med dålig förfrågan,
status: 400
headers: connection=close
Koden nedan anropar api för Review-tjänsten. För tillfället försöker jag bara hämta innehållet.
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('data\n');
req.write('data\n');
req.end();
}
})
.catch((error) => {
console.log(error);
});
}
Funktionen som tar emot denna förfrågan i Review-tjänsten ges nedan,
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);
});
}
Det jag har upptäckt är att begäran från Book-tjänsten når Review-tjänsten och ovanstående funktion, eftersom ovanstående funktion skriver ut alla recensioner i console som den hämtade enligt bookId den fick från begäran från Book-tjänsten. Men Review-tjänsten returnerar inte det resultatet.
Viktigast av allt fungerar båda tjänsterna helt felfritt när jag testar med Postman
Jag har kontrollerat om och om igen om begärans URI är trasig eftersom det kan orsaka ett sådant fel enligt HTTP-statuskoddefinitioner. Men det verkade vara okej eftersom Review-tjänsten hämtar data enligt den begäran.
Jag har också aktiverat cors i min Review-tjänst. Tillät alla HTTP OPTIONS.
Jag använder en 64-bitars Kali Linux-dator.
Något ledtråd skulle vara till stor hjälp. Tack för din tid.
Svar #1
I koden ovan skickar du en kropp med en GET-förfrågan:
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('data\n'); // <-- This writes a request body
req.write('data\n'); // <--
req.end();
Du får vanligtvis inte göra det. För att citera RFC:
Ett nyttolast i ett GET-förfrågningsmeddelande har ingen definierad semantik; att skicka en nyttolastkropp i en GET-förfrågan kan göra att vissa befintliga implementationer avvisar förfrågan.
Det är svårt att vara säker på från koden som ges här, men det är troligt att det är problemet. Servern tar emot förfrågan, den börjar bearbeta den (kör din funktion) och sedan tar servern emot extra oväntad data så den skickar en 400 och stänger anslutningen.
Du behöver tydligt inte de där uppgifterna, så du bör helt enkelt ta bort de raderna. Om du behöver skicka någon data med den här förfrågan måste du antingen inkludera den i förfrågningsrubrikerna/URL:en, eller ändra förfrågan till en POST/PUT/etc., så att du kan inkludera en förfrågningskropp.
(Jag ser att det har gått lite tid sedan du publicerade detta nu, men forhoppningsvis är detta svar hjälpsamt för andra med samma problem!)
