在 vue 3 中获取会停止后端,并且在一次正常工作后啥也不做

Posted

技术标签:

【中文标题】在 vue 3 中获取会停止后端,并且在一次正常工作后啥也不做【英文标题】:Fetch in vue 3 stops backend and does nothing after working fine one time在 vue 3 中获取会停止后端,并且在一次正常工作后什么也不做 【发布时间】:2022-01-10 18:25:37 【问题描述】:

所以,我的问题是,当我尝试登录我的 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("/");
                  );
                
              );
            
          );
        );
      
    ,

注意。 汽车是返回 store.state.cars 的计算值 和 utils 是

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 作为数据库。昨天在我的另一台电脑上一切正常,但我不得不去某个地方使用我的笔记本电脑。也许我的笔记本电脑有问题。我所做的只是安装正面和背面的模块

【问题讨论】:

【参考方案1】:

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

ERR_HTTP_HEADERS_SENT:发送到客户端后无法设置标头

如here所述:

当您尝试对同一个请求发送多个响应时,就会发生该特定错误,通常是由不正确的异步代码引起的。

getAllCars

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

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

getUserById

你说这个处理程序工作得很好,但我真的怀疑——据我所见,这也不应该工作

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

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

正确的模式

    不要同时使用res.status(200).send()res.json() 为了理智起见(至少在你真正知道自己在做什么之前)不要将 promise 与 async/await 混为一谈 async 函数应该返回数据(不要使用没有“参数”的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
    );
;

【讨论】:

感谢您的回答和解释,我了解我做错了什么以及将来应该如何做,现在它可以正常工作。问题是,它以前也可以在我的另一台计算机上运行,​​这令人困惑。无论如何,非常感谢你

以上是关于在 vue 3 中获取会停止后端,并且在一次正常工作后啥也不做的主要内容,如果未能解决你的问题,请参考以下文章

记录在一次前后端分离的项目开发中遇到的坑

pySerial 程序停止正常工作

labview停止循环为啥波形会清除一次

(Nuxt.js/Vue.js) - 脚本只运行一次,更改路由/刷新页面后停止运行

来自 torrent 的文件在 30% 后停止接收碎片

当用户在swift中按下注销按钮时如何停止更新位置