AngularJs $http.post() does not send data

前端 未结 30 1806
我在风中等你
我在风中等你 2020-11-22 02:51

Could anyone tell me why the following statement does not send the post data to the designated url? The url is called but on the server when I print $_POST - I get an empty

相关标签:
30条回答
  • 2020-11-22 03:22

    Didn't find a complete code snippet of how to use $http.post method to send data to the server and why it was not working in this case.

    Explanations of below code snippet...

    1. I am using jQuery $.param function to serialize the JSON data to www post data
    2. Setting the Content-Type in the config variable that will be passed along with the request of angularJS $http.post that instruct the server that we are sending data in www post format.

    3. Notice the $htttp.post method, where I am sending 1st parameter as url, 2nd parameter as data (serialized) and 3rd parameter as config.

    Remaining code is self understood.

    $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;
                });
            };
    

    Look at the code example of $http.post method here.

    0 讨论(0)
  • 2020-11-22 03:22

    I've been using the accepted answer's code (Felipe's code) for a while and it's been working great (thanks, Felipe!).

    However, recently I discovered that it has issues with empty objects or arrays. For example, when submitting this object:

    {
        A: 1,
        B: {
            a: [ ],
        },
        C: [ ],
        D: "2"
    }
    

    PHP doesn't seem to see B and C at all. It gets this:

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

    A look at the actual request in Chrome shows this:

    A: 1
    :
    D: 2
    

    I wrote an alternative code snippet. It seems to work well with my use-cases but I haven't tested it extensively so use with caution.

    I used TypeScript because I like strong typing but it would be easy to convert to pure JS:

    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
        (<any>$httpProvider.defaults).transformRequest = [ function(data: any) {
            if (!angular.isObject(data) || data.toString() == "[object File]") return data;
            return phpize(data).join("&");
        } ];
    } ]);
    

    It's less efficient than Felipe's code but I don't think it matters much since it should be immediate compared to the overall overhead of the HTTP request itself.

    Now PHP shows:

    [
        "A" => "1",
        "B" => [
            "a" => ""
        ],
        "C" => "",
        "D" => "2"
    ]
    

    As far as I know it's not possible to get PHP to recognize that B.a and C are empty arrays, but at least the keys appear, which is important when there's code that relies on the a certain structure even when its essentially empty inside.

    Also note that it converts undefineds and nulls to empty strings.

    0 讨论(0)
  • 2020-11-22 03:23

    If your using PHP this is a easy way to access an array in PHP from an AngularJS POST.

    $params = json_decode(file_get_contents('php://input'),true);
    
    0 讨论(0)
  • 2020-11-22 03:23

    When I had this problem the parameter I was posting turned out to be an array of objects instead of a simple object.

    0 讨论(0)
  • 2020-11-22 03:24

    I have had a similar issue, and I wonder if this can be useful as well: https://stackoverflow.com/a/11443066

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

    Regards,

    0 讨论(0)
  • 2020-11-22 03:24

    Similar to the OP's suggested working format & Denison's answer, except using $http.post instead of just $http and is still dependent on jQuery.

    The good thing about using jQuery here is that complex objects get passed properly; against manually converting into URL parameters which may garble the data.

    $http.post( 'request-url', jQuery.param( { 'message': message } ), {
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
    });
    
    0 讨论(0)
提交回复
热议问题