Node.js: req.params vs req.body

17

我一直在拼凑来自不同教程的代码,使用MEAN技术栈(即使用node、express、angular和mongodb)构建一个基本的待办事项应用程序。其中一份教程介绍了创建GET、POST和DELETE操作的API,但忽略了POST。因此,我把它视为一个挑战,编写一个函数来更新现有的待办事项。虽然我让这个函数工作了,但我遇到了一个涉及req.params的错误,我并不理解。

相关代码:

Node:

在app.js中:

app.put('/api/todos/:_id', ngRoutes.update);

导致:

exports.update = function(req, res){
    var user_id = req.cookies ?
        req.cookies.user_id : undefined;

    Todo.findByIdAndUpdate(req.params._id, 
        { $set: { 
            updated_at : Date.now(), 
            content : req.body.formText
        }}, function (err, todo) {
    if (err) 
        res.send(err)
    Todo.find({ user_id : user_id}, function(err, todos) {
        if (err) res.send(err);
        res.json(todos);
    });
    });
    };

Angular:

    $scope.update = function(id) {
        $http.put('/api/todos/' + id, this.todo)            
        .success(function(data) {
                    console.log(data);
                    $scope.todos = data;
                })
                .error(function(data) {
                    console.log('Error: ' + data);
                });
  };

Jade/HTML:

form(ng-submit="update(todo._id)")
    input.update-form(ng-show="todo.updating" type="text", name="content", ng-model="todo.formText" placeholder="{{todo.content}}")

这个函数工作良好。它更新了相关的待办事项,并返回整个列表,以便重新加载到页面上,显示更新后的值。

然而,如果在节点代码中,我进行更改:

content : req.body.formText

content : req.params.formText

我的HTTP响应中出现了以下错误:

Object { 
message: "Cast to string failed for value "undefined" at path "content"", 
name: "CastError", 
type: "string", 
path: "content" }

即使在函数的其他地方,

req.params._id

这种方法可以很好地检索代办事项的 '_id' 属性,并使用它来在数据库中查找相应的文档。此外,在 Firefox 的开发者工具中查看请求时,在“参数”选项卡下,todo 对象以 JSON 格式显示。

为什么会出现这种情况?使用 req.params 和 req.body 有什么区别,为什么第二个方法可行而第一个不可行?

2个回答

32

req.params 是用于路由参数而非表单数据。

你这个路由中唯一的参数是 _id

app.put('/api/todos/:_id', ...)

文档中提到:

req.params
此属性是一个包含映射到命名路由“参数”的属性的对象。 例如,如果您有路由 /user/:name,则“name”属性可用作 req.params.name。 此对象默认为 {}。

来源:http://expressjs.com/en/4x/api.html#req.params

req.body
包含在请求体中提交的键值对数据。默认情况下,它未定义,并且当您使用解析请求体的中间件(如body-parser和multer)时才会填充。

来源:http://expressjs.com/en/4x/api.html#req.body


谢谢!这让我理解了很多。我仍然有点困惑Firefox开发者工具中的“Params”是指什么,这导致了我的困惑,但它似乎只是指请求体/负载的不同方式。 - Deimyts
1
这也帮助了我。我在使用Postman时混淆了param、params、form-data和x-www-form-urlencoded之间的区别。我使用它来测试Node/Express API与PassportJS,起初无法理解为什么只得到了一些用户字段。我不得不使用x-www-form-urlencoded、req.body和passReqToCallback: true。 - ssedwards

6

req.params 是你在请求的url参数或请求头部发送的一部分。

在postman中的req.params示例

In example above req.params is the data we are sending in postman after ninjas in the 
url.


    route.delete('/ninjas/:id',function(req,res,next)
{
    Ninja.findByIdAndRemove({_id:req.params.id}).then(function(ninja)
    {
        console.log(ninja.toString());
        res.send(ninja);
    })
    .catch(next);

});

req.body is the part you send in body part of requests

在Postman中的req.body示例

req.body是我们在Postman中发送的JSON数据,以便我们可以在post请求体部分访问它。

route.post('/ninjas',function(req,res,next)
{
    Ninja.create(req.body).then(function(ninja)
    {
        console.log("POST"+req.body);
    res.send(ninja);
    })
    .catch(next);

});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接