我正在努力解决一些Express路由,它们的行为不同,即使要执行的代码是相同的.

我希望客户端应用程序按如下方式调用该API:

async search(){

      const query = this.$refs.searchInput.value;
      console.log(query);

      const addressToFetch = "/api/budget/search?q=" + query;
      await fetch(addressToFetch)
        .then((response) => response.json())
        .then((response) => {
          console.log(response);
        });
    }

其中,值query取自以下输入的HTML标记:

              <div class="input-group row text-right">
                <!--flex-nowrap-->
                <div class="col">
                  <input
                    type="text"
                    id="searchInput"
                    name="search"
                    placeholder="Search"
                    ref="searchInput"
                  />
                  <button
                    type="button"
                    class="btn btn-primary btn-search btn-filter"
                    @click="search"
                  >
                    <i class="fa fa-search" aria-hidden="true"></i>
                  </button>

                  <button
                    type="button"
                    class="btn btn-danger"
                    v-if="filteredResults"
                    @click="getExpenses"
                  >
                    Undo
                  </button>
                </div>
              </div>

服务器端应用程序按如下方式处理请求:

app.get("/api/budget/search", verify, async (req, res) => {
  console.log(req.query.q);
  const users = await db
    .collection("users")
    .find({ username: { $regex: req.query.q } })
    .toArray();
  users.forEach((user) => {
    delete user.password;
  });

  res.json(users);
});

身份验证后,该函数返回[],甚至不打印服务器端日志(log).与postman 核对,我可以看到,无论如何,回复是200OK.出于测试目的,我创建了一条不同的路径,其中包含相同的代码.事实证明,新的路由产生了不同的(好的)结果:

app.get("/api/users/search", verify, async (req, res) => {
  console.log(req.query.q);
  const users = await db
    .collection("users")
    .find({ username: { $regex: req.query.q } })
    .toArray();
  users.forEach((user) => {
    delete user.password;
  });

  res.json(users);
});

我把所有的路由都留给你,看看有没有什么问题:

const express = require("express");
const fs = require("fs/promises");
const session = require("express-session");
const { MongoClient } = require("mongodb");
const exp = require("constants");
const uri = "mongodb://mongohost";
const app = express();

const client = new MongoClient(uri);
let db = null;

app.use(express.static(`${__dirname}/public`));
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(
  session({
    secret: "segreto",
    resave: false,
  })
);

function verify(req, res, next) {
  if (req.session.user) {
    next();
  } else {
    res.status(403);
  }
}

app.post("/api/auth/signup", async (req, res) => {});

app.post("/api/auth/signin", async (req, res) => {...});

app.get("/api/budget/whoami", verify, (req, res) => {...});

app.get("/api/budget", verify, async (req, res) => {...});

app.get("/api/budget/:year", verify, async (req, res) => {...});

app.get("/api/budget/:year/:month", verify, async (req, res) => {...});

app.get("/api/budget/:year/:month/:id", verify, async (req, res) => {...});

app.post("/api/budget/:year/:month", verify, async (req, res) => {...});

app.put("/api/budget/:year/:month/:id", verify, async (req, res) => {...});

app.delete("/api/budget/:year/:month/:id", verify, async (req, res) => {...});

app.get("/api/balance", verify, async (req, res) => {...});

app.get("/api/balance/:id", verify, async (req, res) => {...});

app.get("/api/budget/search", verify, async (req, res) => {...});


app.get("/api/users/search", verify, async (req, res) => {...});

app.listen(3000, async () => {
  await client.connect();
  db = client.db("balanceApp");
});

我不明白第一条路由的问题,我能做些什么来解决这个问题吗?非常感谢您的耐心等待.

推荐答案

Express使用path-to-regexp包来匹配您的路由路径.

当你提出GET个请求时

/api/budget/search

PATH-to-regexp程序包的路径为/api/budget/search,当Express从上到下遍历您的路由以查找它匹配的匹配项时:

app.get("/api/budget/:year", verify, async (req, res) => {...});

现在,PATH-to-regexp有一个包含对象的keys数组,每个对象都包含一个包含请求参数的name属性.它一定已经解析了您的单词search,并将其解释为请求参数:year,因此就Express而言,/api/budget/search/api/budget/:year匹配,因此它将请求路由到此处.

你所要做的就是移动这条路由:

app.get("/api/budget/search", verify, async (req, res) => {...});

在这条路由之上:

app.get("/api/budget/:year", verify, async (req, res) => {...});

以便Express有机会进行精确模式匹配.

Javascript相关问答推荐

fetch在本地设置相同来源的cookie,但部署时相同的代码不会设置cookie

Vega中的模运算符

深嵌套的ng-container元素仍然可以在Angular 布局组件中正确渲染内容吗?

React Code不在装载上渲染数据,但在渲染上工作

Snowflake JavaScript存储过程返回成功,尽管预期失败

如何使用JavaScript将文本插入空div

如果Arrow函数返回函数,而不是为useEffect返回NULL,则会出现错误

对路由DOM嵌套路由作出react

连接到游戏的玩家不会在浏览器在线游戏中呈现

JavaScript是否有多个`unfined`?

如何在Node.js中排除导出的JS文件

MarkLogic-earch.suggest不返回任何值

使用jQuery find()获取元素的属性

JavaScript将字符串数字转换为整数

使用API调用的VUE 3键盘输入同步问题

Django模板中未加载JavaScript函数

更改管线时不渲染组件的react

KeyboardEvent:检测到键具有打印的表示形式

ReactJS在类组件中更新上下文

如何使用useparams从react路由中提取id