繁体   English   中英

如何通过 JS fetch 向服务器发送数据/从服务器接收数据

[英]How to send/receive data to/from server via JS fetch

我是 fetch 的新手,我正在尝试将 $ajax 转换为 fetch而无需等待,async .. (直到那里我才成功)。 我正在为服务器使用 Express。

fetch/promise 的基本概念对我来说还不清楚,我不知道如何发送以 881569990078588 格式selected的参数,以及如何从服务器接收它。 我以为我可以用JSON.parse(req.body.data)接收它(从服务器端),我尝试了一些东西但它在客户端和服务器端都给我错误(错误在下面)。

** 我尝试从某人的反馈中获取:POST json 数据,但遗憾的是我无法让它为我工作。 **

任何帮助,将不胜感激。

addProduct(selected) { 
        const orderList = this;

        function post(){
        
            // const data = {
            //     selected:"selected",
            // }        

            fetch('/cart', {
                method:'post',
                headers:{
                    "Accept": "application/json, text/plain, */*",
                    "Content-type": "application/json; charset = UTF-8"
                },
                body: JSON.stringify(selected),
            })
            .then(res => {
                res.json()
                console.log(res)})
            .then(res => console.log(res));
        }
        
        post();
}

服务器端错误: SyntaxError: Unexpected token u in JSON at position 0

客户端错误: Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0

(以下代码是有效的原始 $ajax 代码)

客户端

menuItemClick(target) {
        const selected = this.menuList.data.find(product => product.id == target.dataset.id)
        const selectedIndex = this.orderList.data.findIndex(product => product.id == selected.id)
        if (selectedIndex === -1) {
            selected.count = 1;
            this.orderList.addProduct(selected)
    }



addProduct(selected) { 
        const orderList = this;
        $.ajax({
            url:"http://localhost:8080/cart",
            type:"post",
            dataType: "json",
            data: {data:JSON.stringify(selected)},
            success: function(orderedItem){
                orderList.data.push(orderedItem),
                orderList.orderRender()
            }
        })
        
    }

服务器端

app.use(express.json());
app.use(express.urlencoded({ extended: false }));

app.post("/cart", (req, res) => {
    const bodyData = JSON.parse(req.body.data);
    db.query(
        `INSERT INTO cartData (prodId) VALUES(${bodyData.id})`,(err, rows) => {
            db.query(
                `SELECT cartData.id as orderId, prodName, price, category, count, menuData.Id as id FROM menuData JOIN cartData on menuData.id = cartData.prodId where prodId = ${bodyData.id}`,
                (err, orderedItem) => {
                    res.send({"orderedItem": "${orderedItem[0]}"});
                }
            );
        }
    );
});

你真的很接近,只有几件事:

  1. (客户端)您需要检查 HTTP 是否成功。 不幸的是,当出现网络故障时, fetch只会拒绝其 promise,而不是 HTTP 错误。

  2. (客户端)您需要使用res.json()的返回值,它是一个 promise,因此您想从履行处理程序中返回它。

  3. (客户端)您需要处理错误,或者将 promise 链返回给可以处理的东西。

  4. (服务器端)您发送的是文本[object Object] ,而不是 JSON; 更多如下。

  5. (服务器端)您收到的错误表明服务器端代码存在其他问题; 更多如下。

  6. (服务器端)您的代码存在 SQL 注入攻击的风险 更多如下。

因此,例如,如果您想处理postpost错误并且不向其调用者报告成功/失败:

fetch('/cart', {
    method:'post',
    headers:{
        "Accept": "application/json, text/plain, */*",
        "Content-type": "application/json; charset = UTF-8"
    },
    body: JSON.stringify(selected),
})
.then(res => {
    if (!res.ok) {                                   // ***
        throw new Error("HTTP error " + res.status); // *** #1
    }                                                // ***
    return res.json();                               // *** #2
})
.then(data => {
    // *** Use `data` here
})
.catch(error => {
    // *** Handle/report error here                  // *** #3
});

关于#4,您这样做是为了发送信息:

res.send({"orderedItem": "${orderedItem[0]}"});

send需要一个缓冲区、一个字符串或一个数组。 要将某些内容转换为 JSON 并改为发送,请使用json

res.json({"orderedItem": "${orderedItem[0]}"});

另请注意,这将准确发送此 JSON:

{"orderedItem":"${orderedItem[0]}"}

我怀疑你想要一个模板文字,以便发送orderedItem[0]的值,如下所示:

res.json({"orderedItem": `${orderedItem[0]}`});
// −−−−−−−−−−−−−−−−−−−−−−^−−−−−−−−−−−−−−−−−^

但如果只是orderedItem[0] ,则不需要模板文字,只需:

res.json({"orderedItem": orderedItem[0]});

或者如果你想将它转换为字符串:

res.json({"orderedItem": String(orderedItem[0])});

(您也不需要orderedItem属性名称上的" ,因为您在那里使用的是 object 文字,您没有写 JSON;但在这种情况下它们是无害的,如果您有属性,则需要它们名称中带有-或其他内容。)

关于#5,你说错误是:

未捕获(承诺)SyntaxError:意外令牌 < in JSON at position 0

这表明您收到的是错误,而不是数据,因为您发送的内容中的第一个标记不会是<但如果您发送的是 HTML 错误页面,它就会是。 希望感谢上面的#2,您现在可以找到错误路径,并且能够找出错误是什么。 从代码中不能立即看出错误是什么(除非bodyData.id是文本的,而不是数字的),因此您需要对其进行调试。

关于#6,你有这个模板文字用于创建你的 SQL:

`INSERT INTO cartData (prodId) VALUES(${bodyData.id})`

切勿使用您从客户那里收到的未经净化的信息。 在该模板文字中,您刚刚接受了所提供的内容。 问题是它可能是恶意的,或者只是异想天开的东西。 (让我把你介绍给我的朋友鲍比。)

相反,使用它提供db的任何功能来创建参数化查询 切勿将文本连接与客户端提供的值一起构建 SQL 字符串。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM