【问题标题】:Postman works but fetch() doesnt. Why not?邮递员工作,但 fetch() 没有。为什么不?
【发布时间】:2019-01-19 07:36:18
【问题描述】:

邮递员请求似乎有效,但我无法让 fetch() 处理相同的请求和标头。快把我逼疯了。

客户:

fetch('http://localhost:1234/acts/create', {
    method: 'POST',
    headers: {
        "Content-Type": "application/x-www-form-urlencoded",
    },
    body: JSON.stringify({
        name: 'BARNEY MCGREW!',
        rating: 90,
    })
})

快递:

exports.act_create = function (req, res) {
    console.log(' req >>>>', req.body);
    var act = new Act(
        {
            name: req.body.name,
            rating: req.body.rating
        }
    );

    // res.set('Content-Type', 'application/x-www-form-urlencoded');

    act.save(function (err) {
        if (err) {
            return console.log(err);
        }
        res.send('Act Created successfully')
    })
};

这会生成以下终端输出:

 req >>>> :  [Object: null prototype] { '{"name":"IngleburtHumperdink","rating":10}': '' }
act is:  { _id: 5c4245bea7bb511c20de6b7a }

所以它有点通过但后来我得到ValidationError: Act validation failed: name: Pathnameis required., rating: Path "rating" is required.

路径“名称”也一样。

因此,很难将 json 字符串化对象与传入的名称/评级值匹配。但是从 POST 请求的正文中删除 JSON.stringify 会给我一个req >>>> [Object: null prototype] { '[object Object]': '' }

我在这里做错了什么?

[并且是否有任何好的博客清楚地解释了如何通过正文传递数据,以便可以通过fetch() 毫无问题地访问它? ]

【问题讨论】:

  • 你在哪里打电话fetch?该本地页面的控制台?在 devtools 的 Network 选项卡中使用 fetch 时请显示错误
  • 你在使用body-parser middleware吗?
  • @Hongarrc 是的,使用 fetch 调用 Mongo/Mlab 快递点。所以它在 chrome 浏览器开发工具控制台中。它只是挂在Promise {<pending>} 上,是的,@Oscar 我在我的 app.js 中设置了 bodyParser app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); - 我一直在关注本教程,所以除了productsacts 之外,它都是一样的。 ????
  • @NewbieAid 如果您尝试在控制台中记录req.body.name,输出是什么?
  • 它将记录 undefined – 当 req.body 被记录时,我们可以看到它是一个只包含一个键的对象,而该键恰好是整个字符串化的 JSON。

标签: javascript express fetch


【解决方案1】:

x-www-form-urlencoded 请求正文必须是 name=BARNEY%20MCGREW%21&rating=90

您通过fetch 发送请求,正文为'{"name":"BARNEY MCGREW!","rating":90}'

由于没有=,整个JSON字符串被认为是一个空值的参数名。

因此,您从req.body 中获得了一个对象,其中字符串化的 JSON 显示为键。


通过将数据传递给构造函数来创建URLSearchParams - 替换JSON.stringify

fetch('http://localhost:1234/acts/create', {
    method: 'POST',
    headers: {
        "Content-Type": "application/x-www-form-urlencoded",
    },
    body: new URLSearchParams({
        name: 'BARNEY MCGREW!',
        rating: 90,
    })
})

您的fetch 请求正文现在应该是name=BARNEY%20MCGREW%21&rating=90

这将被正文解析器正确解析为x-www-form-urlencoded 内容。


如果 URLSearchParams 未定义,则有 npm 包会提供它。否则,它所做的就是通过使用= 编码和连接键和值,并使用& 连接每对,来构造一个 URL 参数字符串,可以这样完成:

function URLSearchParams(data) {
    return Object.keys(data).map(key => {
        return `${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`;
    }).join('&');
}

【讨论】:

  • 谢谢@Callum 所以这几乎在那里..我现在在我的终端中得到确认 & MLab 正在保存新条目,但在 Chrome 控制台中它正在标记我认为对x-www-form-urlencoded 来说不是问题的CORS?我的网络应用程序也是如此。标记 CORS,但它可以通过 MLAB?困惑?
  • @NewbieAid 在哪个方面标记 CORS?您收到具体消息了吗?
  • 不同的端口号,可能是问题:home:1 Access to fetch at 'http://localhost:1234/acts/create' from origin 'http://localhost:3000' has been blocked by CORS - 有没有使用 express.Router 设置 no-cors 的快速/简单方法 - 昨晚我试图修复时找不到任何东西这个。
  • 为了进行测试,请将标头 Access-Control-Allow-Origin 添加到您的服务器响应中,并将其设置为 http://localhost:3000。应该看起来像这样res.header("Access-Control-Allow-Origin", "http://localhost:3000")
猜你喜欢
  • 2016-06-17
  • 1970-01-01
  • 2019-08-25
  • 2020-09-20
  • 2018-11-11
  • 1970-01-01
  • 1970-01-01
  • 2019-10-10
  • 2016-11-16
相关资源
最近更新 更多