簡體   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