angularjs 的$http服务中配置transformRequest参数进行post请求,node后端报错

在$http中使用了transformRequest来转换请求数据的格式,但是发现,无论即使我返回的还是原来的数据,只要使用了这个函数,后端就会报错.请求是发送了的.代码如下:

var httpGet = angular.module('HttpGet',[]);
//使用这种方式也是不行哒~~~
/*httpGet.config(function($httpProvider){
    $httpProvider.defaults.transformRequest=function(data){
        console.log(data);
        return data
    }
});*/
httpGet.factory('getData',function($http,$q){
    return function(){
        var defer = $q.defer();
        $http({
            method:'post',
            url:'/api/user',
            data: {name:"code_bunny"},
            headers: {'Authorization':'code_bunny'},
            transformRequest:function(data){
                return data
            }
        }).success(function(data,status,headers,config){
            defer.resolve(data);
        }).error(function(data,status,headers,config){
            defer.reject(data)
        });
        return defer.promise
    }
});

为了测试,我不对请求数据做处理,直接返回data,请求数据确实是发送了的.但是node后端却报错了.错误是 "unexpected token o",但是把transformRequest项删掉,一切正常.请问是什么原因.
node代码:

var express = require('express');
var app = express();
app.use(express.bodyParser());
app.use(express.static(__dirname+''));

app.post('/api/user',function(req,res){
    console.log(req.body);
    res.send(req.body)
});

app.listen(3000);

谢谢大家~~~

阅读 25.5k
3 个回答

看情况似乎是有一个token,然后 transformRequest 之后导致token解析出错。
不知道是不是这个引起的 (/ □ )。

// angularjs 初始化 ng-app="myApp",json静态数据;

var app = angular.module('myApp',[]);
app.controller('myCtrl',function($scope,httpService){
    var obj = {
        'v' : 1,
        'prod_id' : 10,
        't' : 0.6861832864488719,
        'query' : print
    };
    httpService.postDatas('p/prod.json',obj,function(data){
        data = eval(data);
        console.log(data);
        $scope.names = data.ds;
    })
});
app.service("httpService", function ($http) {
    return {
        getDatas: function (url, obj1, succCallBack, errorCallBack) {
            return $http({
                method: "GET",
                url: url,
                params: obj1 || {}
            }).success(function (data) {
                succCallBack && succCallBack(data);
            }).error(function (data) {
                errorCallBack && errorCallBack(data);
            })
        },
        postDatas: function (url, obj1, succCallBack, errorCallBack) {
            return $http({
                method: "POST",
                url: 'p/prod.json',
                data: obj1 || {},
                headers: {'Content-Type': 'application/x-www-form-urlencoded'},
                transformRequest: function (obj) {
                    var str = [];
                    for (var p in obj) {
                        str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
                    }
                    return str.join("&");
                }
            }).success(function (data) {
                succCallBack && succCallBack(data);
            }).error(function (data) {
                errorCallBack && errorCallBack(data);
            })
        }
    }
});

朋友,我理解是完全没必要这么做的:

首先, ng中的$http默认的Content-Typeapplication/json

然后, ng本身是做了参数处理的,给你贴一段源码(~ng1.5.x)中的解释:

AngularJS provides the following default transformations:
  
Request transformations (`$httpProvider.defaults.transformRequest` and `$http.defaults.transformRequest`) is
an array with one function that does the following:
- If the `data` property of the request configuration object contains an object, serialize it
into JSON format.  

所以你的post中的data属性本身就会被ng默认的转换函数做json序列化,如果自己去设置transformRequest配置项的处理函数,当然会出现你描述的问题,再给你来一段源码:

Overriding the Default Transformations Per Request
If you wish to override the request/response transformations only for a single request then provide
`transformRequest` and/or `transformResponse` properties on the configuration object passed
into `$http`.

Note that if you provide these properties on the config object the default transformations will be
overwritten. If you wish to augment the default transformations then you must include them in your
local transformation array.

The following code demonstrates adding a new response transformation to be run after the default response
transformations have been run.
function appendTransform(defaults, transform) {

// We can't guarantee that the default transformation is an array
defaults = angular.isArray(defaults) ? defaults : [defaults];

// Append the new transformation to the defaults
return defaults.concat(transform);
}

$http({
    url: '...',
    method: 'GET',
    transformResponse: appendTransform($http.defaults.transformResponse, function(value) {
      return doTransform(value);
    })
});

最后,如果后端非要难为你(不支持application/json),在ng中用x-www-form-urlencoded方式post也是可以的,可以参考这儿

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题