Путь API с использованием экспресс-маршрутизатора в nodejs

Используя Router Express, я не могу получить такие пути, как http://localhost:5000/api/get и http://localhost:5000/api/get/blah, которые попадают туда, где я хочу. Я знаю, что router.js работает, потому что все, что связано с /api/, работает, но все попадает в ловушку router.js.

например

Вывод Console.log с http://localhost:5000/api/get/blah

попадание в маршрут Catch All API
Запрос API прошел: /api/get/blah
Запрос API прошел через:

Я ожидал, что это попадет в "router.get("/get/:dictionaryId", (req, res) => {", но это не так.

Вывод Console.log с http://localhost:5000/api/get

попадание в маршрут Catch All API
Запрос API передан: /api/get
Запрос API прошел: /

Я ожидал, что это попадет в "router.get("/get", (req, res) => {", но это не так.

Что мне не хватает?

сервер.js

var path = require("path");
var app = express();
var webpack = require("webpack");
var config = require("./webpack.config");
const compiler = webpack(config);
const apiRouter = require("./router"); // Import the API router

var port = 5000;

// Serve static files from the build directory
app.use(express.static(path.join(__dirname, "build")));

app.use("/api/*", apiRouter);

app.use("/api/*", (req, res, next) => {
  console.info(`API request passed through in server.js and currently won't be hit: ${req.originalUrl}`);
  next();
});

// This code makes sure that any request that does not matches a static file
// in the build folder, will just serve index.html. Client side routing is
// going to make sure that the correct content will be loaded.
app.use((req, res, next) => {
  if (/(.ico|.js|.css|.jpg|.png|.map)$/i.test(req.path)) {
    next();
  } else {
    res.header("Cache-Control", "private, no-cache, no-store, must-revalidate");
    res.header("Expires", "-1");
    res.header("Pragma", "no-cache");
    res.sendFile(path.join(__dirname, "build", "index.html"));
  }
});

app.use(
  require("webpack-dev-middleware")(compiler, {
    publicPath: config.output.publicPath,
  }),
);
app.listen(port, function (error) {
  if (error) {
    console.info(error);
  } else {
    console.info("Application running on port: " + port);
  }
});

router.js

const express = require("express");
const router = express.Router();

// Define multiple API endpoints
router.get("/api/get/", (req, res) => {
  console.info("fallen into the get1");
});
router.get("/api/get", (req, res) => {
  console.info("fallen into the get2");
});
router.get("/get", (req, res) => {
  console.info("fallen into the get3");
});
router.get("/get/", (req, res) => {
  console.info("fallen into the get4");
});
router.get("get", (req, res) => {
  console.info("fallen into the get5");
});
router.get("get/", (req, res) => {
  console.info("fallen into the get6");
});

// Define multiple API endpoints
router.get("/get/:dictionaryId", (req, res) => {
  console.info("fallen into the get");
});

router.get("*", (req, res) => {
  console.info("falling into the catch all api route");
  console.info(`API request passed through: ${req.originalUrl}`);
  console.info(`API request passed through: ${req.path}`);
});

module.exports = router;

🤔 А знаете ли вы, что...
JavaScript позволяет создавать асинхронные запросы к серверу с помощью технологии AJAX.


1
57
2

Ответы:

Я не уверен, что вы имеете в виду в своем примере, но я считаю, что вы случайно дублируете пути.

Учитывая, что в вашем Express есть следующее:

app.use("/api/*", apiRouter)

Этот маршрут будет перехватывать все, что имеет путь server.js на первой позиции. Тем не менее, в вашем /api у вас есть следующее:

router.get("/api/get/", (req, res) => {
  console.info("fallen into the get1");
});

Этот фрагмент кода соответствует не router.js, а /api/get. Это означает, что маршрутизатор перебирает все возможные совпадения, первое из которых /api/api/get — это /api/get из:

router.get("/get", (req, res) => {
  console.info("fallen into the get3");
});

Журнал с надписью get3 взят именно из этого.

Вложенные маршрутизаторы применяют «родительский» путь как дерево.


Решено

Проблема в этой части:

app.use("/api/*", apiRouter);

Измените это на:

app.use("/api", apiRouter);

и это работает. Когда вы добавляете звездочку ('*'), он становится маршрутом с подстановочными знаками, и если вы хотите продолжить его использование, вам потребуется более конкретная обработка маршрута. Подробнее об этом можно прочитать в экспресс-документации.