【问题标题】:mongoose: accessing formData [duplicate]猫鼬:访问formData [重复]
【发布时间】:2017-08-18 18:45:26
【问题描述】:

我正在构建一个 geolocationAPI,我正在尝试根据用户提交的最小和最大距离查询位置。但是,我无法在控制器中读取这些值。

我的意见:

<div class="form-group">                        
    <label>Min Distance</label>
    <input type="text" class="form-control text-center" ng-model="minDistance"><br>
</div>
<div class="form-group">                        
    <label>Max Distance</label>
    <input type="text" class="form-control text-center" ng-model="maxDistance"><br>
</div>

我试过这个,把它发送到控制器:

$scope.searchLocations = function () {
    $scope.formData.minDistance = $scope.minDistance;
    $scope.formData.maxDistance = $scope.maxDistance;
    $http.get('/api/places')
        .success(function (data) {
            $scope.searchLocations = data;
            //console.log($scope.formData.minDistance);
        })
        .error(function (data) {
            console.log('Error: ' + data);
        });
}

在我的控制器上我有这个:

exports.find_all_locations_near = function(req, res) {
  if (req.body.minDistance > 0) 
  {
    Location.find({
      geolocation:
        { 
          $near :
          {
              $geometry: { type: "Point",  coordinates: [ lat, lon ] },
              $minDistance: req.body.minDistance,
              $maxDistance: req.body.maxDistance
          }
        }
    }), function(err, location) {
      if (err) {
        //console.log(err);
        res.send(err);
      }
      else if (location =='')
        //res.json({ message: 'No location was found.' });
        res.json({ message: 'No location was found.' });
      else
      {
        res.json(location);
        res.json({ message: 'The end.' });
      }          
    };
  } else 
  {
    Location.find({}, function(err, location) {
      if (err)
        res.send(err);
      res.json(location);
      //res.json(req.body);
    });
  }  
}

我想我不能这样使用 req.body ,对吧?我应该如何访问最小和最大距离的值?

【问题讨论】:

    标签: angularjs node.js express


    【解决方案1】:

    GET 请求没有正文。

    要传递您的搜索值,您可以使用查询字符串参数。

    我们可以编写一个函数来轻松序列化一组命名值,形成一个查询字符串发送到我们的后端。

    function withQuery(url, parameters) {
        const query = Object.keys(parameters)
            .map(function (key) {
                return key + '=' + parameters[key];
            })
            .join('&');
    
        return query.length
            ? url + '?' + query
            : url;
    }
    

    我们将在下面修改后的搜索方法中利用此功能

    $scope.searchLocations = function () {        
        const url = withQuery('api/places', {
            minDistance: $scope.minDistance,
            maxDistance: $scope.maxDistance
        });
    
        $http.get(url)
            .then(function (response) {
                $scope.searchLocations = response.data;
                //console.log($scope.formData.minDistance);
            })
            .catch(function (reason) {
                console.log('Error: ' + reason);
            });
    };
    

    请注意,我们使用 thencatch 而不是 successerror,因为后者已被弃用并且存在问题。

    在您的服务器端代码中,您可以使用请求的 query 属性访问这些值

    exports.find_all_locations_near = function(req, res) {
        const $minDistance = req.query.minDistance;
        const $maxDistance = req.query.maxDistance;
    
        if ($minDistance > 0) {
            Location.find({
                geolocation: { 
                    $near: {
                        $geometry: {
                            type: "Point",
                            coordinates: [lat, lon]
                        },
                        $minDistance,
                        $maxDistance
                    }
                }
            });
    // ...
    };
    

    查询字符串参数以? 开头并采用key=value 的形式,由&amp; 分隔。它们不需要被声明为路由声明的一部分,并且将在传递给回调的 express.Request 值的 query 属性上隐式可用。

    我们可以用下面的 sn-p 来验证这个行为

    app.use('/test', (req, res) => {
      res.send(Object.entries(req.query)
        .map(([key, value]) => `${key} ---> ${value}`)
        .join('<br>')
      );
    });
    

    并在我们的浏览器中导航到/test?x=1&amp;y=hello,这将呈现

    x ---> 1

    y ---> 你好

    注意:虽然req.params 值没有填充查询参数,但可以使用查询参数名称调用req.param 函数来获取其值。例如。 const id = req.param('id')。这让 API 感觉不一致。

    【讨论】:

    • 非常感谢。现在,它显然有效。但现在我收到此错误:GET localhost:3000/api/places?minDistance=10&maxDistance=20 net::ERR_CONNECTION_REFUSED
    • @SuperMonteiro 听起来您的服务器在不同的端口上运行(至少在开发期间)。您需要将您的请求发送到您的 express 应用程序正在侦听的任何端口。例如:'//localhost:5590/api/places'。在 AngularJS 应用程序中,您可以通过注册请求 interceptor 在应用程序的配置阶段全局设置此设置。请注意,这是一种高级技术。
    • 不,我 100% 确信那是正确的端口。查询有问题。当我切换回旧的时,我没有错误。 app.route('/api/places') //.get(geolocation.find_all_locations_near); .get(geolocation.list_all_locations);使用 list all,这只是所有位置的列表,我没有错误。如果我切换到全部查找,我会收到错误消息。有什么想法吗?
    • 应该可以。查询参数不需要在路由上声明。您可以尝试使用路由参数,但查询参数确实就足够了
    • @SuperMonteiro 似乎我们必须使用query 属性而不是params 属性。我写了一个空白的 Express 4 应用程序,它会提取查询字符串。
    【解决方案2】:

    向服务器发送值更改您的发布路径和 $http 方法,否则会导致您的数据暴露于漏洞。

    尽量隐藏数据。

    如果您使用 GET 方法,那么您的数据将作为 params 即在 URL 中

    如果您使用 POST 方法,那么您的数据将进入 req.body

    编辑你的控制器为

    $scope.searchLocations = function () {
       var data = {};
    
        data.minDistance = $scope.minDistance;
        data.maxDistance = $scope.maxDistance;
        $http.post('/api/places',data})
        .success(function(data) {
            $scope.searchLocations = data;
        })
        .error(function(data) {
            console.log('Error: ' + data);
        });
    }
    

    在你的路线上替换你

    app.get('/api/place') to app.post('/api/place')
    

    然后你会得到 req.body.minDistance & req.body.maxDistance

    如果你想使用 GET 请求那么你的 get 方法将是

    $http({
        url: /api/places, 
        method: "GET",
        params: data
     });
    

    从节点访问 req.params.minDistance & req.params.maxDistance

    编码愉快!

    【讨论】:

    • 那么,使用 GET,它们会在 req.params.minDistance 下?
    • 是的,检查我最后添加了 GET 请求
    猜你喜欢
    • 2019-04-23
    • 1970-01-01
    • 2018-10-09
    • 2021-12-04
    • 2015-06-27
    • 2015-04-01
    • 2016-06-20
    • 2017-11-20
    • 2021-10-01
    相关资源
    最近更新 更多