【问题标题】:Body of fetch returning empty object in Next.js API endpoint call在 Next.js API 端点调用中获取返回空对象的主体
【发布时间】:2022-02-15 23:01:39
【问题描述】:

我在 Next.js 中进行 API 调用时遇到了问题,该调用正在删除数据库中的项目。我正在使用 fetch 的“body”字段向 API 发送一个字符串。 fetch 调用是在 Next.JS 页面中进行的,API 端点位于 Next.js 生成的 API 文件夹中。当我从请求中尝试 console.log 正文时,它返回一个空对象。下面将是页面的代码,然后是 API 端点的代码。还将提供来自 API 端点的 console.log 的屏幕截图。

页面

   const handleRemoveItem = useCallback(async(event) => {
        event.preventDefault()
        
        var itemSKU = event.target.value;

        const response = await fetch('/api/SB-RemoveProduct', {
            method:'POST',
            body: itemSKU
            }).then((r) => {
              return r
            }).catch((err) => {
              throw(err)
            });
        var deleteConfirm = await response.json();

        console.log(deleteConfirm);
    },[])

API 端点

export default withSession(async (req, res) => {
    var itemSKU = req.body

    console.log("You are here 1");
    console.log(itemSKU);

    switch (req.method) {
        case 'POST': {
            var productRemoved = await removeProduct(itemSKU, req, res)
            return productRemoved;
            break
        }
        case 'GET': {
            console.log('try writting a route')
            break
        }
        case 'DELETE': {
            console.log('try writting a route')
            break
        }
        case 'UPDATE': {
            console.log('try writting a route')
            break
        }
    }

});

export const removeProduct = async (itemSKU, req, res) => {

    var params = {
        TableName: "products",
        Key: itemSKU
    }
    console.log("You are here 2");
    console.log(itemSKU); // this console.log and the one above both return {}
    DB.delete(params, function(err, data) {
        if (err) {
            console.error("Unable to delete item. Error JSON:", JSON.stringify(err, null, 2));
        } else {
            console.log("DeleteItem succeeded:", JSON.stringify(data, null, 2));
            res.status(200).send(data)
        }
    });
    
}

编辑 1:

收到一些反馈后,我添加了带有 'Content-Type': 'text/plain', 'Accept': 'text/plain' 的标题并以相同的结果结束。我还验证了我传递给正文的变量是一个字符串。下面将是更新代码的页面。

    const handleRemoveItem = useCallback(async(event) => {
        event.preventDefault()
        
        var itemSKU = event.target.value;
        console.log(typeof(itemSKU));

        const response = await fetch('/api/SB-RemoveProduct', {
            method:'POST',
            body: itemSKU,
            mode: "cors",
            headers: {
                'Accept': 'text/plain',
                'Content-Type': 'text/plain'
              },
            }).then((r) => {
              return r
            }).catch((err) => {
              throw(err)
            });
        var deleteConfirm = await response.json();

        console.log(deleteConfirm);
    },[])

编辑 2:

按照以下解决方案的建议,我能够为 itemSKU 返回与以前不同的值。这一次,该项目不是空的,而是以未定义的形式返回。我所做的更改如下:

页面:

const handleRemoveItem = useCallback(async(event) => {
        event.preventDefault()
        
        var itemSKU = event.target.value;
        console.log(typeof(itemSKU));

        const response = await fetch('/api/SB-RemoveProduct', {
            method:'POST',
            body: JSON.stringify({itemSKU}),
            }).then((r) => {
              return r
            }).catch((err) => {
              throw(err)
            });
        var deleteConfirm = await response.json();

        console.log(deleteConfirm);
    },[])

API 端点:

export default withSession(async (req, res) => {
    var itemSKU = req.body.itemSKU //req.body.itemSKU is returning undefined.

    console.log("You are here 1");
    console.log(itemSKU);

    switch (req.method) {
        case 'POST': {
            var productRemoved = await removeProduct(itemSKU, req, res)
            return productRemoved;
            break
        }
        case 'GET': {
            console.log('try writting a route')
            break
        }
        case 'DELETE': {
            console.log('try writting a route')
            break
        }
        case 'UPDATE': {
            console.log('try writting a route')
            break
        }
    }

});

export const removeProduct = async (itemSKU, req, res) => {

    var params = {
        TableName: "products",
        Key: itemSKU
    }
    console.log("You are here 2");
    console.log(itemSKU);
    // DB.delete(params, function(err, data) {
    //     if (err) {
    //         console.error("Unable to delete item. Error JSON:", JSON.stringify(err, null, 2));
    //     } else {
    //         console.log("DeleteItem succeeded:", JSON.stringify(data, null, 2));
    //         res.status(200).send(data)
    //     }
    // });
    
}

【问题讨论】:

  • 您正在发送text/plain 请求正文。那是你想要发送的吗? API 是否配置为处理此类请求内容类型?
  • 所以通常我会在向请求正文传递信息时使用 JSON.stringify(),但这样做会返回完全相同的结果。
  • 您还需要设置适当的内容类型标头
  • 抱歉,我还是个新手开发者,您介意解释一下内容类型标头以及我需要将其更改为什么吗?

标签: javascript node.js reactjs next.js fetch-api


【解决方案1】:

删除标题,包括Content-type: plain/text,然后...

在您的请求中,更改

body: itemSKU,

body: JSON.stringify({ itemSKU });

在您的 API 中,您可以

console.log('req.body.itemSKU', req.body.itemSKU)

最终……

//client side
fetch('/api/...', { method: 'POST', body: JSON.stringify({...}))
.then(res => res.json())
.then(data => console.log('data', data)); 
//prints { value1: 'abc', value2: 'efg'}

然后在 API 方面

export default async(req, res) => {

       console.log('req.body.itemSKU', req.body.itemSKU);

       res.json({ value1: 'abc', value2: 'efg'})
}

【讨论】:

  • 我尝试使用这种方法,实际上我得到了一个 undefined 的值。
  • 如果每个回答都清晰准确会更好。确切地说,什么是未定义的? req.body.itemSKU ?您是否尝试过 console.log(req.body) 并查看它包含的内容?您是否像建议的那样删除了所有标题(例如内容类型)?
  • codesandbox.io/s/musing-paper-rf5vym?file=/pages/index.js 在终端和控制台中查看 console.log。
  • 我在原始帖子中对返回未定义的内容进行了编辑。它是 req.body.itemSKU。我看不出代码沙箱中的请求和我的请求有什么重大区别。我对 body 使用相同的方法和值。
  • 我能够解决问题,中间件很好,不是原因。添加具有 application/json 值的内容类型标头解决了该问题。但是,我认为我的原始问题不是在使用 .stringify 函数时将 itemSKU 包裹在大括号中。
猜你喜欢
  • 1970-01-01
  • 2020-05-09
  • 1970-01-01
  • 1970-01-01
  • 2020-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-16
相关资源
最近更新 更多