AngularJs $http.post() nie wysyła danych

Czy ktoś mógłby mi powiedzieć, dlaczego poniższe oświadczenie nie wysyła danych postu na wskazany adres url? Url jest wywoływany, ale na serwerze kiedy drukuje $_POST-dostaję pustą tablicę. Jeśli wydrukowałem wiadomość w konsoli przed dodaniem jej do danych-pokazuje poprawną treść.

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

Próbowałem również z danymi jako ciąg znaków (z tym samym wynikiem):

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

Wydaje się działać, gdy używam go w następującym formacie:

$http({
    method: 'POST',
    url: 'request-url',
    data: "message=" + message,
    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
});
Ale czy jest na to sposób z $http.post () - i czy zawsze muszę dołączyć nagłówek, aby działał? Uważam, że powyższy typ zawartości określa format wysyłanych danych, ale czy mogę wysłać je jako obiekt javascript?
Author: Gaurav Aggarwal, 2013-10-08

30 answers

Miałem ten sam problem z używaniem asp.net MVC i znaleźli rozwiązanie tutaj

Jest wiele zamieszania wśród nowicjuszy AngularJS co do tego, dlaczego $http funkcje skrótu usługi ($http.post(), itp.) nie wydaje się można je wymieniać za pomocą odpowiedników jQuery (jQuery.post(), itd.)

Różnica polega na tym, jak jQueryi AngularJS serializują i przesyłają dane. Zasadniczo problem leży w języku serwera wybór nie jest w stanie zrozumieć natywnie transmisji AngularJS ... Domyślnie, jQuery przesyła dane za pomocą

Content-Type: x-www-form-urlencoded

I znana foo=bar&baz=moe serializacja.

AngularJS, jednak przesyła dane za pomocą

Content-Type: application/json 

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

Serializacja JSON, która niestety niektóre języki serwerów WWW - szczególnie PHP - Nie unserializuj natywnie.

Działa jak urok.

kod

// 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;
  }];
});
 339
Author: Felipe Miosso,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-15 11:32:00

Nie jest to zbyt jasne powyżej, ale jeśli otrzymujesz żądanie w PHP, możesz użyć:

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

Aby uzyskać dostęp do tablicy w PHP z Posta AngularJS.

 111
Author: Don F,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-03 01:14:30

Możesz ustawić domyślny "Content-Type" w następujący sposób:

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

O FORMACIE data:

$http.post i $http.metody put akceptują dowolny obiekt JavaScript (lub łańcuch znaków) jako swój parametr danych. Jeśli dane są obiektem JavaScript, domyślnie zostaną przekonwertowane na ciąg JSON.

Spróbuj użyć tej odmiany

function sendData($scope) {
    $http({
        url: 'request-url',
        method: "POST",
        data: { 'message' : message }
    })
    .then(function(response) {
            // success
    }, 
    function(response) { // optional
            // failed
    });
}
 75
Author: Denison Luz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-24 19:40:51

Miałem podobny problem i zastanawiam się, czy to też może się przydać: 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'}
})

Pozdrawiam,

 55
Author: ericson.cepeda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:38

Lubię używać funkcji do konwersji obiektów na post params.

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'}
})
 33
Author: Rômulo Collopy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-04 14:30:21

W końcu udało się to rozwiązać w angular 1.4 używając $httpParamSerializerJQLike

Zobacz https://github.com/angular/angular.js/issues/6039

.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'
})})
 29
Author: Stetzon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-10 16:25:33

Używam jQuery param z AngularJS post requrest. Oto przykład ... Utwórz moduł aplikacji AngularJS, gdzie {[2] } jest zdefiniowany przez ng-app w kodzie HTML.

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

Teraz stwórzmy Kontroler logowania i zamieść e-mail i hasło.

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

Nie lubię exaplain kodu, jest to dość proste do zrozumienia :) zauważ, że param pochodzi z jQuery, więc musisz zainstalować zarówno jQuery jak i AngularJS, aby działał. Oto zrzut ekranu.

Tutaj wpisz opis obrazka

Mam nadzieję, że to pomoże. Dzięki!
 16
Author: Madan Sapkota,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-17 12:24:20

Miałem ten sam problem z AngularJS i Node.js + Express 4 + Router

Router oczekuje danych z żądania posta w treści. To ciało było zawsze puste, jeśli podążałem za przykładem z Angular Docs

Zapis 1

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

But if i used it in the data

Notacja 2

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

Edit 1:

Inaczej węzeł.js router będzie oczekiwać danych w req.body if used notation 1:

req.body.msg

Który wysyła również informacje jako JSON payload. To jest lepiej w niektórych przypadkach, gdy masz tablice w json i x-www-form-urlencoded da pewne problemy.

Zadziałało. Mam nadzieję, że to pomoże.
 9
Author: alknows,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-07 20:07:04

W przeciwieństwie do JQuery i ze względu na pedanterię, Angular używa formatu JSON do postu data transfer z Klienta na serwer (jQuery stosuje x-www-form-urlencoded przypuszczalnie, chociaż JQuery i Angular używa JSON do przypisywania danych). Dlatego istnieją dwie części problemu: w części klienta js i w części serwera. Więc potrzebujesz:

  1. Umieść część klienta js w ten sposób:

    $http({
    method: 'POST',
    url: 'request-url',
    data: {'message': 'Hello world'}
    });
    

I

  1. Napisz w części serwera aby otrzymać dane od klienta (jeśli jest to php).

            $data               = file_get_contents("php://input");
            $dataJsonDecode     = json_decode($data);
            $message            = $dataJsonDecode->message;
            echo $message;     //'Hello world'
    

Uwaga: $_POST nie będzie działać!

Rozwiązanie działa dobrze dla mnie, mam nadzieję, i dla Ciebie.

 9
Author: Roman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-22 04:25:26

Aby wysłać dane metodą Post Z $http z angularjs należy zmienić

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

 8
Author: BERGUIGA Mohamed Amine,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-16 10:50:52

Na podstawie odpowiedzi @ felipe-miosso:

  1. pobierz go jako moduł AngularJS z tutaj ,
  2. Install it
  3. Dodaj go do swojej aplikacji:

    var app = angular.module('my_app', [ ... , 'httpPostFix']);
    
 7
Author: Renaud,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-19 20:28:19

Nie mam reputacji komentować, ale w odpowiedzi / dodatku do odpowiedzi Dona F:

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

Do funkcji json_decode należy dodać drugi parametr true, aby poprawnie zwrócić tablicę asocjacyjną:

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

 5
Author: Esten,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-21 21:15:59

Kątowe

  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

public class AcceptJobParams
        {
            public int jobId { get; set; }
        }

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

            return Ok();
        }
 5
Author: Malcolm Swaine,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-22 15:07:12

Ten kod rozwiązał problem dla mnie. Jest to rozwiązanie na poziomie aplikacji:

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";
  }
]);
 5
Author: Spartak Lalaj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-27 15:21:55

Dodaj to do pliku js:

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

I dodaj to do pliku serwera:

$params = json_decode(file_get_contents('php://input'), true);
To powinno zadziałać.
 5
Author: Jesus Erwin Suarez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-22 13:16:16

Ja również stanąłem przed podobnym problemem i robiłem coś takiego i to nie zadziałało. Mój Kontroler Spring nie był w stanie odczytać parametru danych.

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

Ale czytając to forum i API Doc, próbowałem podążać w ten sposób i to działało dla mnie. Jeśli ktoś ma podobny problem, możesz spróbować również poniżej.

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

Proszę sprawdzić https://docs.angularjs.org/api/ng/service / $http#post za to co robi param config. {data: '"id": "1"'} - Mapa łańcuchów lub obiektów, które zostanie włączony do adresu URL?data = "id: 1"

 4
Author: Viraj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-22 13:16:19

Jest to prawdopodobnie późna odpowiedź, ale myślę, że najodpowiedniejszym sposobem jest użycie tego samego fragmentu kodu podczas wykonywania żądania " get " używając you $httpParamSerializer będzie musiał wstrzyknąć go do kontrolera możesz więc po prostu wykonać następujące czynności bez konieczności używania Jquery , $http.post(url,$httpParamSerializer({param:val}))

app.controller('ctrl',function($scope,$http,$httpParamSerializer){
    $http.post(url,$httpParamSerializer({param:val,secondParam:secondVal}));
}
 4
Author: oneLeggedChicken,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-24 18:20:25

W moim przypadku rozwiązuję problem tak:

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;

Musisz użyć JSON.stringify dla każdego param zawierającego obiekt JSON, a następnie zbuduj swój obiekt danych za pomocą"$.param": -)

NB: mój "objJSON" jest obiektem JSON zawierającym tablicę, liczbę całkowitą, ciąg znaków i zawartość html. Jego całkowity rozmiar to > 3500 znaków.

 4
Author: bArraxas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-28 11:07:05

I know has akceptowane odpowiedz. Ale podążanie za nimi może pomóc przyszłym czytelnikom, jeśli odpowiedź im nie odpowiada z jakiegokolwiek powodu.

Angular nie działa tak samo jak jQuery. Podczas gdy próbowałem postępować zgodnie z instrukcją modyfikacji kątowej $httpprovider, napotkałem inne problemy. Np. używam codeigniter, w którym $this->input->is_ajax_request() funkcja zawsze zawodziła (która została napisana przez innego programistę i używana globalnie, więc nie można zmienić) mówiąc, że to nie było prawdziwe żądanie ajax.

Aby to rozwiązać, ja skorzystał z pomocy deferred promise. Testowałem go w Firefoksie, ie9 i zadziałało.

Mam następującą funkcję zdefiniowaną na zewnątrz dowolny kod kątowy. Ta funkcja sprawia, że zwykłe wywołanie jQuery ajax i zwraca obiekt deferred/promise (I ' m still learning).

function getjQueryAjax(url, obj){
    return $.ajax({
        type: 'post',
        url: url,
        cache: true,
        data: obj
    });
}

W takim razie nazywam go kodem kątowym używając poniższego kodu. Należy pamiętać, że musimy zaktualizować $scope ręcznie za pomocą $scope.$apply().

    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!");
    });

To może nie być idealne odpowiedź, ale to pozwoliło mi używać Połączeń jQuery ajax z angular i pozwoliło mi zaktualizować $scope.

 3
Author: Nis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-22 01:02:42

Miałem ten sam problem w Expressie .. aby rozwiązać problem, musisz użyć bodyparser do analizy obiektów json przed wysłaniem żądań http ..

app.use(bodyParser.json());
 3
Author: msoliman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-02 22:05:57

Używam asp.net WCF webservices with angular js and below code "przepracowany": {]}

 $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;                    
       })
Mam nadzieję, że to pomoże.
 3
Author: Mehdi Rostami,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-20 14:39:52

Nie znaleziono pełnego fragmentu kodu jak używać $http.metoda post do wysyłania danych do serwera i dlaczego nie działa w tym przypadku.

Objaśnienia poniższego fragmentu kodu...

  1. używam jQuery $.funkcja param do serializacji danych JSON do danych www Post
  2. Ustawienie Content-Type W Zmiennej konfiguracyjnej, która będzie przekazywana wraz z żądaniem angularJS $ http.post, który instruuje Serwer, że wysyłamy dane w www post format.

  3. Zwróć uwagę na $http.metoda post, gdzie 1. parametr wysyłam jako url, 2. parametr jako dane (serializowane) i 3. parametr jako config.

Pozostały kod jest zrozumiały.

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

Spójrz na przykład kodu $http.metoda post tutaj .

 3
Author: Sheo Narayan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-11 03:54:14

Jeśli używasz PHP jest to łatwy sposób na dostęp do tablicy w PHP z AngularJS POST.

$params = json_decode(file_get_contents('php://input'),true);
 3
Author: Luis Felipe Barnett V,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-11 22:57:42

Jeśli używasz Angular >= 1.4, Oto najczystsze rozwiązanie za pomocą serializera dostarczonego przez Angular :

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';
});
Możesz to zrobić w dowolnym miejscu swojej aplikacji:]}
$http({
  method: 'POST',
  url: '/requesturl',
  data: {
    param1: 'value1',
    param2: 'value2'
  }
});

I poprawnie serializuje dane jako param1=value1&param2=value2 i wysyła je do /requesturl z nagłówkiem application/x-www-form-urlencoded; charset=utf-8 Content-Type, tak jak zwykle oczekuje się tego przy żądaniach POST na punktach końcowych.

TL; DR

Podczas moich badań odkryłem, że odpowiedź na ten problem przychodzi wiele różnych smaków; niektóre są bardzo zawiłe i zależą od niestandardowych funkcji, niektóre zależą od jQuery, a niektóre są niekompletne w sugerowaniu, że wystarczy ustawić nagłówek.

Jeśli ustawisz nagłówek Content-Type, punkt końcowy będzie wyświetlał dane postu, ale nie będą one w standardowym formacie, ponieważ jeśli nie podasz ciągu znaków jako data lub ręcznie serializujesz obiektu danych, to wszystkie będą serializowane jako JSON domyślnie i mogą być błędnie zinterpretowane na serwerze. punkt końcowy.

Np. jeśli poprawny serializer nie został ustawiony w powyższym przykładzie, będzie widoczny w punkcie końcowym jako:

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

I może to prowadzić do nieoczekiwanego parsowania, np. ASP.NET traktuje go jako nazwę parametru null, z {"param1":"value1","param2":"value2"} jako wartością; lub Fiddler interpretuje go w inny sposób, z {"param1":"value1","param2":"value2"} jako nazwą parametru, a null jako wartością.

 3
Author: Saeb Amini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-18 09:46:57

Podobny do sugerowanego formatu roboczego OP & odpowiedź Denisona, z wyjątkiem używania $http.post zamiast tylko $http i jest nadal zależny od jQuery.

Dobrą rzeczą w używaniu jQuery jest to, że złożone obiekty są przekazywane prawidłowo; przed ręczną konwersją na parametry URL, które mogą garbować dane.

$http.post( 'request-url', jQuery.param( { 'message': message } ), {
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
});
 3
Author: Benjamin Intal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-24 03:20:15

Kiedy miałem ten problem, parametr, który publikowałem, okazał się tablicą obiektów zamiast prostego obiektu.

 2
Author: D. Kermott,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-09 20:32:11

Właśnie zaktualizowałem angular 1.2 do 1.3, znalazłem problem w kodzie. Transformacja zasobu doprowadzi do nieskończonej pętli, ponieważ (myślę) $promise ponownie trzyma ten sam obiekt. Może to komuś pomoże...

Mógłbym to naprawić przez:

[...]
  /**
 * 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) {
[...]
 2
Author: tom_w,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-03 19:06:41

Od jakiegoś czasu używam akceptowanego kodu odpowiedzi (Felipe ' s code) i działa świetnie (dzięki, Felipe!).

Jednak ostatnio odkryłem, że ma problemy z pustymi obiektami lub tablicami. Na przykład podczas przesyłania tego obiektu:

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

PHP w ogóle nie widzi B i C. Dostaje to:

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

Spojrzenie na rzeczywiste żądanie w Chrome pokazuje to:

A: 1
:
D: 2

Napisałem fragment kodu alternatywnego. Wydaje się, że działa dobrze z moimi przypadkami użycia, ale Nie testowałem go intensywnie, więc używaj ostrożnie.

Użyłem TypeScript, ponieważ lubię mocne pisanie, ale łatwo byłoby przekonwertować na czysty 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("&");
    } ];
} ]);

Jest mniej wydajny niż Kod Felipe, ale nie sądzę, że ma to duże znaczenie, ponieważ powinien być natychmiastowy w porównaniu z ogólnym obciążeniem samego żądania HTTP.

Teraz PHP pokazuje:

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

Z tego co wiem to nie jest możliwe aby PHP rozpoznało że B. A i C są pustymi tablicami, ale przynajmniej klucze pojawiają się, co jest ważne, gdy istnieje kod, który opiera się na pewnej strukturze, nawet jeśli jest zasadniczo pusty w środku.

Zauważ również, że konwertuje niezdefiniowane s I null s do pustych łańcuchów.

 2
Author: obe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-06 22:40:24

Rozwiązałem to poniższymi kodami:

Strona Klienta (Js):

     $http({
                url: me.serverPath,
                method: 'POST',
                data: data,
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
            }).
                success(function (serverData) {
                    console.log("ServerData:", serverData);
    ......

Zauważ, że dane są obiektem.

Na serwerze (ASP.NET MVC):

[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;
        }

I' Allowcrossitejsonattribute ' jest potrzebne dla żądań między domenami:

public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*");
            base.OnActionExecuting(filterContext);
        }
    }
Mam nadzieję, że to się przydało.
 1
Author: pixparker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-23 11:04:46

To nie wina angular ' a. Angular jest przeznaczony do pracy w świecie JSON. Więc kiedy usługa $ http wysyła żądanie AJAX, wysyła wszystkie Twoje dane jako ładunek, a nie jako dane formularzy, aby Twoja aplikacja zaplecza mogła je obsłużyć. Ale jQuery robi pewne rzeczy wewnętrznie. Poinstruowujesz moduł $ajax jQuery, aby bindował form-data jako JSON, ale przed wysłaniem żądania AJAX serializował JSON i dodał nagłówek application/x-www-form-urlencoded. W ten sposób Twoja aplikacja zaplecza może otrzymać dane formularza w postaci parametrów posta, a nie JSON.

Ale można zmodyfikować domyślne zachowanie usługi $http przez

  1. dodawanie nagłówka
  2. serializacja json

$httpParamSerializerJQLike jest wbudowaną usługą angular, która serializuje json w ten sam sposób $.param robi jQuery.

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

Jeśli potrzebujesz wtyczki do serializacji danych formularza w JSON, użyj tej https://github.com/marioizquierdo/jquery.serializeJSON

 1
Author: Uday Hiwarale,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-29 12:35:40