在 vue 3 中获取停止后端并且在一次正常工作后什么都不做

Fetch in vue 3 stops backend and does nothing after working fine one time

所以,我的问题是当我尝试登录我的 vue 应用程序时,当我尝试从它获取对象数组时,后端会自动停止。

更具体一点。 这是我从数据库中获取对象的“尝试”。

let url = utils.url;
    let requestParam = utils.globalRequestParameters;
    requestParam.method = "GET";
    requestParam.body = null;
    if (cars.value.length == 0) {
      fetch(url + "cars", requestParam).then((res) =>
        res.json().then(async (res) => {
          store.dispatch("Car/fetchCars", res);
          fetch(url + "users", requestParam).then((users) =>
            users.json().then((users) => {
              for (let car of res) {
                let userCar = Object.values(users).find(
                  (a) => a.id == car.userId
                );
                car.userName = userCar.lastName + " " + userCar.firstName;
              }
            })
          );
        })
      );
    }

And login in view Login.vue

let requestParameters = utils.globalRequestParameters;
        requestParameters.method = "POST";
        requestParameters.body = JSON.stringify(data);

        fetch(utils.url + "login", requestParameters).then((res) => {
          res.json().then((res) => {
            this.mesaj = res.message;
            console.log("token:" + res.token);
            if (res.token) {
              localStorage.setItem("token", res.token);
              console.log("token:" + res.token);
              console.log("id:" + res.id);
              let id = res.id;
              requestParameters.method = "GET";
              requestParameters.body = null;
              this.$store.dispatch("login", true);
              fetch(utils.url + "users/" + id, requestParameters).then(
                (res) => {
                  res.json().then((res) => {
                    console.log("Jos de tot");
                    this.$store.dispatch("User/setUser", res);
                    console.log(this.$store.state.User.user);
                    this.$router.push("/");
                  });
                }
              );
            }
          });
        });
      }
    },

注意。 cars 是 return store.state.cars 的计算值 实用程序是

let url = "http://127.0.0.1:3000/";

let globalRequestParameters = {
  method: "GET",
  mode: "cors",
  cache: "no-cache",
  credentials: "same-origin",
  headers: {
    "Content-Type": "application/json",
  },
  redirect: "follow",
  referrerPolicy: "no-referrer",
};

module.exports.globalRequestParameters = globalRequestParameters;
module.exports.url = url;

此处在第一次获取时后端停止,并且未完成获取。

后端路由是


router.get('/cars', async (req, res) => {
    res.json(await functions.getAllCars(req,res));
})

getAllCars = async (req, res) => {
  const snapshot = await db.collection("Cars").get();
  let cars = [];
  snapshot.forEach((doc) => {
    let car = {
      id: doc.id,
      userId: doc.data().userId,
      manufacturer: doc.data().manufacturer,
      model: doc.data().model,
      color: doc.data().color,
      plate: doc.data().plate,
      price: doc.data().price,
      description: doc.data().description
    };
    cars.push(car);
  });

  res.status(200).send(cars);
  return
};

router.get("/users/:id", async (req, res) => {
  res.json(await functions.getUserById(req.params.id, res));
});

getUserById =  (id, res) => {
   db
    .collection("Users")
    .doc(id)
    .get()
    .then((response) => {
      let user = {};
      user.id = response.id;
      user.firstName = response.data().firstName;
      user.lastName = response.data().lastName;
      user.gender = response.data().gender;
      user.jobTitle = response.data().jobTitle;
      user.phone = response.data().phone;
      user.email = response.data().email;
      user.isAdmin = response.data().isAdmin;
      res.status(200).send(user);
      return
    })
    .catch((err) => {
      res.status(404).send({ message: "User not found" });
      return
    });
};

用户被正确检索,我通过控制台日志在控制台中看到它,但我在终端和控制台中得到的消息是:

*作为最后的说明。我使用 vue 3,node.js 版本 16.13.0 和 Firestore 作为数据库。昨天在我的另一台电脑上一切正常,但我不得不去某个地方使用我的笔记本电脑。也许我的笔记本电脑有问题。我所做的只是安装正面和背面的模块

我认为这与 Vue 无关 - 这只是您的 Express 后端代码的问题

ERR_HTTP_HEADERS_SENT: Cannot set headers after they are sent to the client

如所述here

That particular error occurs whenever you try to send more than one response to the same request and is usually caused by improper asynchronous code.

getAllCars

getAllCars 是内部带有 await 的异步函数 - 一旦这个 await 被命中(连同 db.collection("Cars").get() 调用),函数 returns在 res.json(await functions.getAllCars(req,res));

等待的承诺

当数据库调用完成时,将执行该方法的其余部分,包括 res.status(200).send(cars) - 这会将 cars 数组发送到客户端和 returns undefined (这就是简单的 return 所做的)并且执行 res.json(undefined) 导致上面的错误(您正在尝试发送第二个响应)

getUserById

你说这个处理程序工作正常,但我真的很怀疑 - 据我所知,这也不应该工作

您正在用 res.json(await functions.getUserById(req.params.id, res)); 调用它。要 await 实际做某事,等待的函数必须 return 一个 Promise(通过在内部使用 await 隐式或显式)或一般 "thenable" objectgetUserById 函数 return 什么都没有(then()catch() 中的 return 语句不算数!...这些是不同的函数)

这个问题可以通过 return db.collection("Users").doc(id).get().then() 来解决,但是你会得到与 getAllCars 情况相同的错误

正确的模式

  1. 不要同时使用 res.status(200).send()res.json()
  2. 为了理智起见(至少在你真正知道自己在做什么之前)不要将承诺与 async/await
  3. 混在一起
  4. async 函数应该 return 数据(不要在没有“参数”的情况下使用 return

以下代码显示了基于 Promise 和 async/await 风格(从某种意义上说,它是“伪代码”,我没有测试过它,但希望你能理解)

router.get('/cars', async (req, res) => {
  try {  
    const response = await functions.getAllCars()
    res.status(200).json(response);
  } catch() {
    res.sendStatus(500)
  }
})

getAllCars = async () => {
  const snapshot = await db.collection("Cars").get();
  let cars = [];
  snapshot.forEach((doc) => {
    let car = {
      id: doc.id,
      userId: doc.data().userId,
      manufacturer: doc.data().manufacturer,
      model: doc.data().model,
      color: doc.data().color,
      plate: doc.data().plate,
      price: doc.data().price,
      description: doc.data().description
    };
    cars.push(car);
  });

  // res.status(200).send(cars); //* should be handled by caller
  return cars  //* return the data
};

router.get("/users/:id", async (req, res) => {
  functions.getUserById(req.params.id)
    .then((response) =>  {
      if(response === null)
        res.status(404).json({ message: "User not found" });
      else
        res.status(200).json(response);
    })
    .catch(er) {
      res.status(500).send(er.message)
    }
});

getUserById =  (id) => {
   return db  //* return the promise
    .collection("Users")
    .doc(id)
    .get()
    .then((response) => {
      let user = {};
      user.id = response.id;
      user.firstName = response.data().firstName;
      user.lastName = response.data().lastName;
      user.gender = response.data().gender;
      user.jobTitle = response.data().jobTitle;
      user.phone = response.data().phone;
      user.email = response.data().email;
      user.isAdmin = response.data().isAdmin;
      // res.status(200).send(user); //* should be handled by caller
      return user //* return the data
    })
    .catch((err) => {    
      return null
    });
};