Ajax DELETE请求路径不一致

Ajax DELETE request path inconsistency

我设置了一个快速服务器来处理不同的请求,其中一个是删除请求。它有时有效,有时给出 404。我注意到它发送的 url 是不同的。因此,如果我更改我的服务器代码以处理一条路径,它会一直工作,直到客户端发送一条不同的路径。我无法理解为什么它发送不同的 urls 并且不一致。我对网络编程很陌生;还是个学生可能是我遗漏了一些非常基本的东西。

正在从

发送请求

http://localhost:3000/notes

页。

昨天使用此路径发送请求:

今天的请求是:

以防万一图像无法加载,这些是 url:

http://localhost:3000/api/notes/id

http://localhost:3000/notes/api/notes/id

这是客户端请求:(我已经验证它使用正确的值调用删除)

    var deleteNote = function(id) {
       return $.ajax({
       url: "api/notes/" + id,
       method: "DELETE"
      });
    };

这是服务器代码:

    app.delete("/api/notes/:id", (req, res) => {
        let chosenNoteToDelete = req.params.id;

        fs.readFile(__dirname + "/db/db.json", (err, data) => {
         if(err){
           throw err;
         }
        let json = JSON.parse(data);

        for(let i=0; i<json.length; i++){
            if(json[i].id === chosenNoteToDelete){
               json.splice(i,1);
            }
        }

        fs.writeFile(__dirname + "/db/db.json", JSON.stringify(json), (err) => {
            if(err){
                throw err;
            }
            res.send("Successfully deleted");
        })

      })

    });

谁能帮我理解为什么不一致?我如何在服务器上处理它?

从这里更改客户端代码:

var deleteNote = function(id) {
   return $.ajax({
   url: "api/notes/" + id,
   method: "DELETE"
  });
};

对此:

var deleteNote = function(id) {
   return $.ajax({
   url: "/api/notes/" + id,
   method: "DELETE"
  });
};

您的相对路径告诉 jQuery 将您的路径与页面 URL 的路径合并。你不需要相对路径。你总是希望它是 /api/notes/id 所以你需要前导斜杠。


服务器代码中需要清理的其他一些东西。

  1. 使用 console.log(err) 或某种类似的记录机制记录所有可能的错误。

  2. 永远不要在异步回调中在您的服务器中写入 if (err) throw err。那对你没有好处,因为没有人能发现那个错误。相反,您必须始终记录错误,然后通过发送错误响应来处理错误。

  3. 当从可能抛出错误的外部源解析 JSON 时,请在其周围使用 try/catch

  4. 当您 .splice() 一个正在迭代的数组时,您需要在处理 .splice() 之后 return 或者您需要更正迭代索引 (因为你只是将数组元素向下移动,所以你会错过数组中的下一个项目)或者你需要向后迭代数组,所以 .splice() 操作不会影响迭代。

这是您的代码的固定版本:

app.delete("/api/notes/:id", (req, res) => {
    let chosenNoteToDelete = req.params.id;
    fs.readFile(__dirname + "/db/db.json", (err, data) => {
        if (err) {
            console.log(err);
            res.sendStatus(500);
            return;
        }
        try {
            let json = JSON.parse(data);
        } catch(e) {
            console.log(err);
            res.sendStatus(500);
            return;
        }

        for (let i = 0; i < json.length; i++) {
            if (json[i].id === chosenNoteToDelete) {
                json.splice(i, 1);
                return;
            }
        }

        fs.writeFile(__dirname + "/db/db.json", JSON.stringify(json), (err) => {
            if (err) {
                console.log(err);
                res.sendStatus(500);
                return;
            }
            res.send("Successfully deleted");
        });
    });
});

而且,如果找不到 chosenNote,这里有一个使用 fs.promisesasync/await 的更清晰的实现,具有更集中的错误处理和检测:

const fsp = require('fs').promises;
const path = require('path');

app.delete("/api/notes/:id", async (req, res) => {
    let chosenNoteToDelete = req.params.id;
    let dataFilename = path.join(__dirname, "/db/db.json");
    try {
        let data = await fsp.readFile(dataFilename);
        let dataArray = JSON.parse(data);
        // iterate array backwards so .splice() doesn't cause us to miss elements of the array
        let found = false;
        for (let i = dataArray.length - 1; i >= 0; i--) {
            if (dataArray[i].id === chosenNoteToDelete) {
                found = true;
                dataArray.splice(i, 1);
            }
        }
        if (found) {
            await fsp.writeFile(dataFilename, JSON.stringify(dataArray));
            res.send("Successfully deleted");
        } else {
            res.status(404).send(`Note id ${chosenNoteToDelete} not found.`);
        }

    } catch(e) {
        console.log(e);
        res.sendStatus(500);
    }
});