AngularJs $ http.post()不发送数据

AngularJs $http.post() does not send data

谁能告诉我为什么以下声明不会将发布数据发送到指定的网址? 当我打印$ _POST时,在服务器上调用url - 我得到一个空数组。 如果我在将数据添加到数据之前在控制台中打印消息 - 它会显示正确的内容。

1
$http.post('request-url',  { 'message' : message });

我也尝试将数据作为字符串(具有相同的结果):

1
$http.post('request-url', "message=" + message);

当我以下列格式使用它时,它似乎正在工作:

1
2
3
4
5
6
$http({
    method: 'POST',
    url: 'request-url',
    data:"message=" + message,
    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
});

但有没有办法用$ http.post()来做 - 并且我总是必须包含标题才能使它工作? 我相信上面的内容类型是指定发送数据的格式,但我可以将其作为javascript对象发送吗?


我使用asp.net MVC遇到了同样的问题,并在此处找到了解决方案

There is much confusion among newcomers to AngularJS as to why the
$http service shorthand functions ($http.post(), etc.) don’t appear to
be swappable with the jQuery equivalents (jQuery.post(), etc.)

The difference is in how jQuery and AngularJS serialize and transmit the data. Fundamentally, the problem lies with your server language of choice being unable to understand AngularJS’s transmission natively ... By default, jQuery transmits data using

1
Content-Type: x-www-form-urlencoded

and the familiar foo=bar&baz=moe serialization.

AngularJS, however, transmits data using

1
Content-Type: application/json

and {"foo":"bar","baz":"moe" }

JSON serialization, which unfortunately some Web server languages—notably
PHP—do not unserialize natively.

奇迹般有效。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// Your app's root module...
angular.module('MyModule', [], function($httpProvider) {
  // Use x-www-form-urlencoded Content-Type
  $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';

  /**
   * The workhorse; converts an object to x-www-form-urlencoded serialization.
   * @param {Object} obj
   * @return {String}
   */
  var param = function(obj) {
    var query = '', name, value, fullSubName, subName, subValue, innerObj, i;

    for(name in obj) {
      value = obj[name];

      if(value instanceof Array) {
        for(i=0; i<value.length; ++i) {
          subValue = value[i];
          fullSubName = name + '[' + i + ']';
          innerObj = {};
          innerObj[fullSubName] = subValue;
          query += param(innerObj) + '&';
        }
      }
      else if(value instanceof Object) {
        for(subName in value) {
          subValue = value[subName];
          fullSubName = name + '[' + subName + ']';
          innerObj = {};
          innerObj[fullSubName] = subValue;
          query += param(innerObj) + '&';
        }
      }
      else if(value !== undefined && value !== null)
        query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&';
    }

    return query.length ? query.substr(0, query.length - 1) : query;
  };

  // Override $http service's default transformRequest
  $httpProvider.defaults.transformRequest = [function(data) {
    return angular.isObject(data) && String(data) !== '[object File]' ? param(data) : data;
  }];
});


上面不是很清楚,但如果您在PHP中收到请求,您可以使用:

<5233>

从AngularJS POST访问PHP中的数组。


您可以像这样设置默认的"Content-Type":

1
$http.defaults.headers.post["Content-Type"] ="application/x-www-form-urlencoded";

关于data格式:

The $http.post and $http.put methods accept any JavaScript object (or a string) value as their data parameter. If data is a JavaScript object it will be, by default, converted to a JSON string.

尝试使用此变体

1
2
3
4
5
6
7
8
9
10
11
12
13
function sendData($scope) {
    $http({
        url: 'request-url',
        method:"POST",
        data: { 'message' : message }
    })
    .then(function(response) {
            // success
    },
    function(response) { // optional
            // failed
    });
}


我有一个类似的问题,我想知道这是否也有用:https://stackoverflow.com/a/11443066

1
2
3
4
5
6
7
var xsrf = $.param({fkey:"key"});
$http({
    method: 'POST',
    url: url,
    data: xsrf,
    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})

问候,


我喜欢使用函数将对象转换为post params。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
myobject = {'one':'1','two':'2','three':'3'}

Object.toparams = function ObjecttoParams(obj) {
    var p = [];
    for (var key in obj) {
        p.push(key + '=' + encodeURIComponent(obj[key]));
    }
    return p.join('&');
};

$http({
    method: 'POST',
    url: url,
    data: Object.toparams(myobject),
    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})

最后使用$ httpParamSerializerJQLike在角度1.4中解决了这个问题

请参阅https://github.com/angular/angular.js/issues/6039

1
2
3
4
5
6
7
8
9
10
11
12
13
.controller('myCtrl', function($http, $httpParamSerializerJQLike) {
$http({
  method: 'POST',
  url: baseUrl,
  data: $httpParamSerializerJQLike({
   "user":{
     "email":"[email protected]",
     "password":"123456"
    }
  }),
  headers:
    'Content-Type': 'application/x-www-form-urlencoded'
})})


我使用jQuery param和AngularJS post requrest。下面是一个示例...创建AngularJS应用程序模块,其中myapp在HTML代码中使用ng-app定义。

1
var app = angular.module('myapp', []);

现在让我们创建一个Login控制器和POST电子邮件和密码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
app.controller('LoginController', ['$scope', '$http', function ($scope, $http) {
    // default post header
    $http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
    // send login data
    $http({
        method: 'POST',
        url: 'https://example.com/user/login',
        data: $.param({
            email: $scope.email,
            password: $scope.password
        }),
        headers: {'Content-Type': 'application/x-www-form-urlencoded'}
    }).success(function (data, status, headers, config) {
        // handle success things
    }).error(function (data, status, headers, config) {
        // handle error things
    });
}]);

我不喜欢扩展代码,它很容易理解:)注意param来自jQuery,所以你必须同时安装jQuery和AngularJS才能使它工作。这是一个截图。

enter image description here

希望这是有帮助的。谢谢!


我对AngularJS和Node.js + Express 4 +路由器也有同样的问题

路由器期望来自帖子请求的数据在正文中。如果我按照Angular Docs的例子,这个主体总是空的

符号1

1
$http.post('/someUrl', {msg:'hello word!'})

但如果我在数据中使用它

符号2

1
2
3
4
5
6
7
$http({
       withCredentials: false,
       method: 'post',
       url: yourUrl,
       headers: {'Content-Type': 'application/x-www-form-urlencoded'},
       data: postData
 });

编辑1:

否则node.js路由器将使用req.body中的数据(如果使用符号1):

1
req.body.msg

其中还将信息作为JSON有效负载发送。在json和x-www-form-urlencoded中有数组的某些情况下,这会更好。

有效。希望能帮助到你。


与JQuery不同,为了迂回曲折,Angular使用JSON格式进行POST
从客户端到服务器的数据传输(JQuery应用x-www-form-urlencoded,尽管JQuery和Angular使用JSON进行数据输入)。因此有两个问题:js客户端部分和服务器部分。所以你需要:

  • 把js Angular客户端部分放到这样:

    1
    2
    3
    4
    5
    $http({
    method: 'POST',
    url: 'request-url',
    data: {'message': 'Hello world'}
    });
  • 写入您的服务器部分以从客户端接收数据(如果它是php)。

    1
    2
    3
    4
            $data               = file_get_contents("php://input");
            $dataJsonDecode     = json_decode($data);
            $message            = $dataJsonDecode->message;
            echo $message;     //'Hello world'
  • 注意:$ _POST不起作用!

    解决方案对我来说很好,希望和你。


    要使用带有$http angularjs的Post方法发送数据,您需要更改

    data:"message=" + messagedata: $.param({message:message})


    建立@ felipe-miosso的答案:

  • 从这里下载它作为AngularJS模块,
  • 安装它
  • 将其添加到您的应用程序:

    1
    var app = angular.module('my_app', [ ... , 'httpPostFix']);

  • 1
    2
    3
    4
    5
    6
    7
    8
      var payload = $.param({ jobId: 2 });

                    this.$http({
                        method: 'POST',
                        url: 'web/api/ResourceAction/processfile',
                        data: payload,
                        headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
                    });

    WebAPI 2

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class AcceptJobParams
            {
                public int jobId { get; set; }
            }

            public IHttpActionResult ProcessFile([FromBody]AcceptJobParams thing)
            {
                // do something with fileName parameter

                return Ok();
            }


    我没有评论的声誉,但作为对Don F答案的回应/补充:

    $params = json_decode(file_get_contents('php://input'));

    需要将true的第二个参数添加到json_decode函数中,以便正确返回关联数组:

    $params = json_decode(file_get_contents('php://input'), true);


    这段代码为我解决了这个问题。它是一个应用程序级解决方案:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    moduleName.config(['$httpProvider',
      function($httpProvider) {
        $httpProvider.defaults.transformRequest.push(function(data) {
            var requestStr;
            if (data) {
                data = JSON.parse(data);
                for (var key in data) {
                    if (requestStr) {
                        requestStr +="&" + key +"=" + data[key];
                    } else {
                        requestStr = key +"=" + data[key];
                    }
                }
            }
            return requestStr;
        });
        $httpProvider.defaults.headers.post["Content-Type"] ="application/x-www-form-urlencoded";
      }
    ]);


    在你的js文件中添加:

    1
    $http.defaults.headers.post["Content-Type"] ="application/x-www-form-urlencoded";

    并将其添加到您的服务器文件:

    1
    $params = json_decode(file_get_contents('php://input'), true);

    这应该工作。


    在我的情况下,我解决这个问题:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    var deferred = $q.defer();

    $http({
        method: 'POST',
        url: 'myUri',
        data: $.param({ param1: 'blablabla', param2: JSON.stringify(objJSON) }),
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
    }).then(
        function(res) {
            console.log('succes !', res.data);
            deferred.resolve(res.data);
        },
        function(err) {
            console.log('error...', err);
            deferred.resolve(err);
        }
    );
    return deferred.promise;

    您需要为包含JSON对象的每个param使用JSON.stringify,然后使用"$ .param"构建数据对象:-)

    注意:我的"objJSON"是一个包含数组,整数,字符串和html内容的JSON对象。他的总大小超过3500个字符。


    这可能是一个迟到的答案,但我认为最合适的方法是在使用$httpParamSerializer执行"获取"请求时使用相同的代码角度使用$httpParamSerializer将其注入您的控制器
    所以你可以简单地执行以下操作而不必使用Jquery,
    $http.post(url,$httpParamSerializer({param:val}))

    1
    2
    3
    app.controller('ctrl',function($scope,$http,$httpParamSerializer){
        $http.post(url,$httpParamSerializer({param:val,secondParam:secondVal}));
    }

    我也面临类似的问题,我正在做这样的事情,但没有奏效。我的Spring控制器无法读取数据参数。

    1
    2
    var paramsVal={data:'"id":"1"'};
      $http.post("Request URL",  {params: paramsVal});

    但是阅读这个论坛和API Doc,我尝试了以下方式,这对我有用。
    如果有人也有类似的问题,你也可以尝试以下方式。

    1
    2
    3
    4
    5
    6
    $http({
          method: 'POST',
          url:"Request URL",          
          params: paramsVal,
          headers: {'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'}
                });

    请查看https://docs.angularjs.org/api/ng/service/$http#post以了解param配置的功能。
    {data:'"id":"1"'} - 将转换为URL的字符串或对象的映射?data ="id:1"


    我在express中有同样的问题..要解决你必须使用bodyparser解析json对象才能发送http请求..

    1
    app.use(bodyParser.json());


    我知道已经接受了答案。但是,如果答案因任何原因不适合他们,以下可能会对未来的读者有所帮助。

    Angular不像jQuery那样执行ajax。当我尝试按照指南修改angular $httpprovider时,我遇到了其他问题。例如。我使用codeigniter,其中$this->input->is_ajax_request()函数总是失败(由另一个程序员编写并全局使用,因此无法更改)说这不是真正的ajax请求。

    为了解决这个问题,我接受了延期承诺的帮助。我在Firefox中测试了它,ie9并且它工作正常。

    我在任何角度代码之外定义了跟随函数。这个函数定期进行jquery ajax调用并返回deferred / promise(我还在学习)对象。

    1
    2
    3
    4
    5
    6
    7
    8
    function getjQueryAjax(url, obj){
        return $.ajax({
            type: 'post',
            url: url,
            cache: true,
            data: obj
        });
    }

    然后我使用以下代码将其称为角度代码。请注意,我们必须使用$scope.$apply()手动更新$scope

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
        var data = {
            media:"video",
            scope:"movies"
        };
        var rPromise = getjQueryAjax("myController/getMeTypes" , data);
        rPromise.success(function(response){
            console.log(response);
            $scope.$apply(function(){
                $scope.testData = JSON.parse(response);
                console.log($scope.testData);
            });
        }).error(function(){
            console.log("AJAX failed!");
        });

    这可能不是一个完美的答案,但它允许我使用带有角度的jquery ajax调用并允许我更新$scope


    没有找到如何使用$ http.post方法将数据发送到服务器的完整代码片段以及为什么它在这种情况下不起作用。

    以下代码片段的说明......

  • 我正在使用jQuery $ .param函数将JSON数据序列化为www post数据
  • 在config变量中设置Content-Type,该变量将与angularJS $ http.post的请求一起传递,该请求指示服务器我们以www post格式发送数据。

  • 注意$ htttp.post方法,我将第一个参数作为url发送,第二个参数作为数据(序列化),第三个参数作为config。

  • 剩下的代码是自我理解的。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    $scope.SendData = function () {
               // use $.param jQuery function to serialize data from JSON
                var data = $.param({
                    fName: $scope.firstName,
                    lName: $scope.lastName
                });

                var config = {
                    headers : {
                        'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'
                    }
                }

                $http.post('/ServerRequest/PostDataResponse', data, config)
                .success(function (data, status, headers, config) {
                    $scope.PostDataResponse = data;
                })
                .error(function (data, status, header, config) {
                    $scope.ResponseDetails ="Data:" + data +
                       "<hr />status:" + status +
                       "<hr />headers:" + header +
                       "<hr />config:" + config;
                });
            };

    在这里查看$ http.post方法的代码示例。


    如果你使用PHP,这是一个从AngularJS POST访问PHP数组的简单方法。

    1
    $params = json_decode(file_get_contents('php://input'),true);


    类似于OP建议的工作格式和Denison的答案,除了使用$http.post而不仅仅是$http并且仍然依赖于jQuery。

    在这里使用jQuery的好处是复杂的对象可以正常传递;反对手动转换为可能使数据混乱的URL参数。

    1
    2
    3
    $http.post( 'request-url', jQuery.param( { 'message': message } ), {
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
    });

    如果使用Angular> = 1.4,这是使用Angular提供的序列化程序的最干净的解决方案:

    1
    2
    3
    4
    5
    angular.module('yourModule')
      .config(function ($httpProvider, $httpParamSerializerJQLikeProvider){
        $httpProvider.defaults.transformRequest.unshift($httpParamSerializerJQLikeProvider.$get());
        $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8';
    });

    然后您可以在应用中的任何位置执行此操作:

    1
    2
    3
    4
    5
    6
    7
    8
    $http({
      method: 'POST',
      url: '/requesturl',
      data: {
        param1: 'value1',
        param2: 'value2'
      }
    });

    它将正确地将数据序列化为param1=value1¶m2=value2并使用application/x-www-form-urlencoded; charset=utf-8 Content-Type标头将其发送到/requesturl,因为它通常在端点上使用POST请求。

    TL; DR

    在我的研究过程中,我发现这个问题的答案有很多不同的风格;有些是非常复杂的,依赖于自定义函数,有些依赖于jQuery,有些不完整,建议你只需要设置标题。

    如果你只是设置Content-Type标题,结束点将看到POST数据,但它不会是标准格式,因为除非你提供一个字符串作为你的data,或者手动序列化你的数据对象,它将默认情况下都被序列化为JSON,并且可能在端点处被错误地解释。

    例如如果在上面的示例中未设置正确的序列化程序,则会在端点中看到:

    1
    {"param1":"value1","param2":"value2"}

    这可能导致意外的解析,例如ASP.NET将其视为null参数名称,其中{"param1":"value1","param2":"value2"}为值;或者Fiddler以另一种方式解释它,{"param1":"value1","param2":"value2"}作为参数名称,null作为值。


    I am using asp.net WCF webservices with angular js and below code
    worked:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     $http({
            contentType:"application/json; charset=utf-8",//required
            method:"POST",
            url: '../../operation/Service.svc/user_forget',
            dataType:"json",//optional
            data:{"uid_or_phone": $scope.forgettel,"user_email": $scope.forgetemail },
            async:"isAsync"//optional

           }).success( function (response) {

             $scope.userforgeterror = response.d;                    
           })

    希望能帮助到你。


    我已经使用了接受的答案代码(Felipe的代码)一段时间了,它一直很好用(谢谢,Felipe!)。

    但是,最近我发现它存在空对象或数组的问题。
    例如,提交此对象时:

    1
    2
    3
    4
    5
    6
    7
    8
    {
        A: 1,
        B: {
            a: [ ],
        },
        C: [ ],
        D:"2"
    }

    PHP似乎根本没有看到B和C.它得到了这个:

    1
    2
    3
    4
    [
       "A" =>"1",
       "B" =>"2"
    ]

    查看Chrome中的实际请求会显示以下内容:

    1
    2
    3
    A: 1
    :
    D: 2

    我写了一个替代代码片段。它似乎与我的用例很好,但我没有广泛测试它,所以谨慎使用。

    我使用TypeScript是因为我喜欢强类型,但很容易转换为纯JS:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    angular.module("MyModule").config(["$httpProvider", function($httpProvider: ng.IHttpProvider) {
        // Use x-www-form-urlencoded Content-Type
        $httpProvider.defaults.headers.post["Content-Type"] ="application/x-www-form-urlencoded;charset=utf-8";

        function phpize(obj: Object | any[], depth: number = 1): string[] {
            var arr: string[] = [ ];
            angular.forEach(obj, (value: any, key: string) => {
                if (angular.isObject(value) || angular.isArray(value)) {
                    var arrInner: string[] = phpize(value, depth + 1);
                    var tmpKey: string;
                    var encodedKey = encodeURIComponent(key);
                    if (depth == 1) tmpKey = encodedKey;
                    else tmpKey = `[${encodedKey}]`;
                    if (arrInner.length == 0) {
                        arr.push(`${tmpKey}=`);
                    }
                    else {
                        arr = arr.concat(arrInner.map(inner => `${tmpKey}${inner}`));
                    }
                }
                else {
                    var encodedKey = encodeURIComponent(key);
                    var encodedValue;
                    if (angular.isUndefined(value) || value === null) encodedValue ="";
                    else encodedValue = encodeURIComponent(value);

                    if (depth == 1) {
                        arr.push(`${encodedKey}=${encodedValue}`);
                    }
                    else {
                        arr.push(`[${encodedKey}]=${encodedValue}`);
                    }
                }
            });
            return arr;
        }

        // Override $http service's default transformRequest
        ($httpProvider.defaults).transformRequest = [ function(data: any) {
            if (!angular.isObject(data) || data.toString() =="[object File]") return data;
            return phpize(data).join("&");
        } ];
    } ]);

    它的效率低于Felipe的代码,但我认为这并不重要,因为与HTTP请求本身的总体开销相比,它应该是立竿见影的。

    现在PHP显示:

    1
    2
    3
    4
    5
    6
    7
    8
    [
       "A" =>"1",
       "B" => [
           "a" =>""
        ],
       "C" =>"",
       "D" =>"2"
    ]

    据我所知,不可能让PHP认识到B.a和C是空数组,但至少出现了键,这对于依赖于某个结构的代码很重要,即使它本身是空的。

    另请注意,它将undefined和null转换为空字符串。


    刚刚从角度1.2更新到1.3,在代码中发现了一个问题。转换资源将导致无限循环,因为(我认为)$ promise再次保持相同的对象。也许它会帮助某人......

    我可以解决这个问题:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    [...]
      /**
     * The workhorse; converts an object to x-www-form-urlencoded serialization.
     * @param {Object} obj
     * @return {String}
     */
    var param = function (obj) {
    var query = '', name, value, fullSubName, subName, subValue, innerObj, i;

    angular.forEach(obj, function(value, name) {
    +    if(name.indexOf("$promise") != -1) {
    +        return;
    +    }

        value = obj[name];
        if (value instanceof Array) {
            for (i = 0; i < value.length; ++i) {
    [...]

    当我遇到这个问题时,我发布的参数被证明是一个对象数组而不是一个简单的对象。


    只需将要发送的数据作为第二个参数:

    1
    $http.post('request-url',  message);

    另一种形式也有效:

    1
    $http.post('request-url',  { params: { paramName: value } });

    确保paramName与您正在调用的函数的参数名称完全匹配。

    来源:AngularJS发布快捷方式


    我通过以下代码解决了这个问题

    客户端(Js):

    1
    2
    3
    4
    5
    6
    7
    8
    9
         $http({
                    url: me.serverPath,
                    method: 'POST',
                    data: data,
                    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                }).
                    success(function (serverData) {
                        console.log("ServerData:", serverData);
        ......

    注意数据是一个对象。

    在服务器上(ASP.NET MVC):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    [AllowCrossSiteJson]
            public string Api()
            {
                var data = JsonConvert.DeserializeObject<AgentRequest>(Request.Form[0]);
                if (data == null) return"Null Request";
                var bl = Page.Bl = new Core(this);

                return data.methodName;
            }

    并且跨域请求需要'AllowCrossSiteJsonAttribute':

    1
    2
    3
    4
    5
    6
    7
    8
    public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
        {
            public override void OnActionExecuting(ActionExecutingContext filterContext)
            {
                filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin","*");
                base.OnActionExecuting(filterContext);
            }
        }

    希望这很有用。


    这不是角度的错。 Angular旨在在JSON世界中工作。因此,当$ http服务发送AJAX请求时,它会将所有数据作为有效负载发送,而不是作为表单数据发送,以便后端应用程序可以处理它。但是jQuery在内部做了一些事情。您指示jQuery的$ ajax模块将表单数据绑定为JSON,但在发送AJAX请求之前,它序列化了JSON并添加了application/x-www-form-urlencoded标头。这样,您的后端应用程序能够以post参数的形式接收表单数据,而不是JSON。

    但您可以修改角度$ http服务的默认行为

  • 添加标题
  • 序列化json
  • $ httpParamSerializerJQLike是angular的内置服务,它以与.JQuery的$ .param相同的方式序列化json。

    1
    2
    3
    4
    5
    6
    7
    8
    $http({
        method: 'POST',
        url: 'request-url',
        data: $httpParamSerializerJQLike(json-form-data),
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8;'
        }
    });

    如果你需要一个插件来首先将表单数据序列化为JSON,请使用这个https://github.com/marioizquierdo/jquery.serializeJSON


    我写了一个小的PHP辅助函数,它允许两种类型的输入参数:

    1
    2
    3
    4
    5
    function getArgs () {
        if ($input = file_get_contents('php://input') && $input_params = json_decode($input,true))
            return $input_params + $_POST + $_GET;
        return $_POST + $_GET;
    }

    用法:

    1
    2
    3
    4
    5
    6
    7
    8
    <?php
        include("util.php"); # above code
        $request = getArgs();

        $myVar ="";
        if (isset($request['myVar']))
            $myVar = $request['myVar'];
    ?>

    因此,您的JavaScript无需更改。


    通过使用非常简单的方法,我们可以遵循:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     $http({
            url :"submit_form_adv.php",
            method : 'POST',
            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('&');
            },
            data : {sample_id : 100, sample_name: 'Abin John'},

        }).success(function(data, status, headers, config) {

        }).error(function(ata, status, headers, config) {

        });

    我遇到了这个问题,问题是我在使用上述标题发帖时无法获取数据,即

    1
    2
    3
    4
    headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/x-www-form-urlencoded'
    }

    在使用jquery Ajax时,我们通常在后端服务器上的response.body中获取数据,但是在实现Angular ajax时,数据并没有响应。

    1
    request.getParameterMap.keySet().iterator().next()

    找到了简单的解决方案

    http://jasonwatmore.com/post/2014/04/18/post-a-simple-string-value-from-angularjs-to-net-web-api

    1
    return $http.post(Config.apiUrl + '/example/processfile', '"' + fileName + '"');

    用这种方式。没必要写那么多

    1
     isAuth = $http.post("Yr URL", {username: username, password: password});

    并在nodejs后端

    1
    2
    3
    4
    5
    6
    app.post("Yr URL",function(req,resp)
    {

      var username = req.body.username||req.param('username');
      var password = req.body.password||req.param('password');
    }

    我希望这有帮助


    刚刚提出@ FelipeMiosso的现代化版本答案:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    .config(["$httpProvider", function ($httpProvider) {

      function buildKey(parentKey, subKey) {
        return parentKey +"[" + subKey +"]";
      }

      function buildObject(key, value) {
        var object = {};
        object[key] = value;
        return object;
      }

      function join(array) {
        return array.filter(function (entry) {
          return entry;
        }).join("&");
      }

      function arrayToQueryString(parentKey, array) {
        return join(array.map(function (value, subKey) {
          return toQueryString(buildObject(buildKey(parentKey, subKey), value));
        }));
      }

      function objectToQueryString(parentKey, object) {
        return join(Object.keys(object).map(function (subKey) {
          return toQueryString(buildObject(buildKey(parentKey, subKey), object[subKey]));
        }));
      }

      function toQueryString(input) {
        return join(Object.keys(input).map(function (key) {
          var value = input[key];
          if (value instanceof Array) {
            return arrayToQueryString(key, value);
          } else if (value instanceof Object) {
            return objectToQueryString(key, value);
          } else if (undefined !== value && null !== value) {
            return encodeURIComponent(key) +"=" + encodeURIComponent(value);
          } else {
            return"";
          }
        }));
      }

      function isQueryStringEligible(input) {
        return null !== input &&"object" === typeof input &&"[object File]" !== String(input);
      }

      var interceptor = [function () {
        return {
          request: function (config) {
            if (0 <= ["post","put","patch"].indexOf(config.method.toLowerCase()) && isQueryStringEligible(config.data)) {
              config.headers["Content-Type"] ="application/x-www-form-urlencoded;charset=utf-8";
              config.data = toQueryString(config.data);
            }
            return config;
          }
        };
      }];

      $httpProvider.interceptors.push(interceptor);

    }])

    ES6版本:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    .config(["$httpProvider", function ($httpProvider) {

     "use strict";

      const buildKey = (parentKey, subKey) => `${parentKey}[${subKey}]`;

      const buildObject = (key, value) => ({ [key]: value });

      const join = (array) => array.filter((entry) => entry).join("&");

      const arrayToQueryString = (parentKey, array) =>
        join(array.map((value, subKey) =>
          toQueryString(buildObject(buildKey(parentKey, subKey), value))));

      const objectToQueryString = (parentKey, object) =>
        join(Object.keys(object).map((subKey) =>
          toQueryString(buildObject(buildKey(parentKey, subKey), object[subKey]))));

      const toQueryString = (input) => join(Object.keys(input).map((key) => {
        const value = input[key];
        if (value instanceof Array) {
          return arrayToQueryString(key, value);
        } else if (value instanceof Object) {
          return objectToQueryString(key, value);
        } else if (undefined !== value && null !== value) {
          return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
        } else {
          return"";
        }
      }));

      const isQueryStringEligible = (input) =>
        null !== input &&"object" === typeof input &&"[object File]" !== String(input);

      const interceptor = [() => ({
        request(config) {
          if (0 <= ["post","put","patch"].indexOf(config.method.toLowerCase()) && isQueryStringEligible(config.data)) {
            config.headers["Content-Type"] ="application/x-www-form-urlencoded;charset=utf-8";
            config.data = toQueryString(config.data);
          }
          return config;
        }
      })];

      $httpProvider.interceptors.push(interceptor);

    }])