节点js从角度PUT调用接收错误的数据

时间:2014-10-31 18:45:13

标签: javascript angularjs node.js

我实现了一个以角度为单位的rest-crud客户端,它将数据发送到节点api(我也实现了)

当我尝试使用ngResource从form-> angular发送数据到节点api时

  cmsApp.factory('Misc', ['$resource', function($resource) {
      return $resource('/api/misc/:id', {}, {
          'update': { method:'PUT' } // the $resource obj comes with save/query/get/delete but lacks the update-put method
      });
  }]);

因此我收到错误

  Error: invalid json

现在,我在this (old) article

之后找到了解决方法
 cmsApp.config(function ($httpProvider) {
      $httpProvider.defaults.transformRequest = function (data) {
          var str = [];
          for (var p in data) {
              data[p] !== undefined && str.push(encodeURIComponent(p) + '=' + encodeURIComponent(data[p]));
          }
          return str.join('&');
      };
      $httpProvider.defaults.headers.put['Content-Type'] = $httpProvider.defaults.headers.post['Content-Type'] = 
      'application/x-www-form-urlencoded; charset=UTF-8';
  });

这个技巧有点可行,但会破坏数组中的所有字符串,例如,如果我有一个像

这样的字符串
 "foo bar"

我得到的另一面是

  {
    '0': 'f',
    '1': 'o',
    '2': 'o',
    '3': ' ',
    '4': 'b',
    '5': 'a',
    '6': 'r'
  }

这显然就像无法使用的数据一样。

我想知道正确的方法,或者是否有任何其他正确的模式,以使这一点正确。

附录A

nodejs接收器代码

    router.route('/misc/:misctype')
    .put(function(req, res) {
        console.log(req.body.text_label);
    });

3 个答案:

答案 0 :(得分:1)

为什么不将您的数据作为json发送?您自己实现两端,并在两者中使用javascript。 JSON非常适合这种用例。例如,在角度你会做类似的事情:

// in some template (template.tpl.html)
<form>
  field
  <input name="name" ng-model="someObject.field"></input>
  other field
  <input name="email" ng-model="someObject.otherField"></input>
  <button ng-click="sendData">Submit</button>
</form>

//in the controller (myController.js)
$scope.someObject = {};
$scope.sendData = function () {
    doSomeValidation();
    $http.put('http://www.myservice.com/api/whatever', someObject)
    .success(function(result){
         console.log('it worked!'); 
     });
}

$ http服务知道默认编码为JSON,而ng-model允许您轻松绑定到表单元素,因此没有理由将表单库带入其中。然后在节点后端你只需JSON.parse(request.body)或者如果你使用Express就可以使用中间件来做。

有关$ http对象的信息,您可以查看该主题的角度文档here

答案 1 :(得分:0)

尝试使用其他内容类型

"application/json;charset=utf-8"

答案 2 :(得分:0)

事实证明,这个问题与我可以避免所有混乱的事实有关。

cmsApp.config(function ($httpProvider) { ..... }

部分,只是将我发送的对象设置为json,因为,首先我有这个

Misc.update({ id:'text_descr_assoc' }, $scope.description);

并通过在json obj中转换它,并删除现在无用的cmsApp.config部分,一切都很顺利

Misc.update({ id:'text_descr_assoc' }, {"my_key":$scope.description});