AngularJS http http.post () no envía datos


¿Podría alguien decirme por qué la siguiente declaración no envía los datos del post a la url designada? Se llama a la url pero en el servidor cuando imprimo $_POST-obtengo una matriz vacía. Si imprimo el mensaje en la consola antes de agregarlo a los datos, muestra el contenido correcto.

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

También lo he probado con los datos como cadena (con el mismo resultado):

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

Parece estar funcionando cuando lo uso en el siguiente formato:

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

Pero hay una manera de hacerlo con el http http.post () - ¿y siempre tengo que incluir el encabezado para que funcione? Creo que el tipo de contenido anterior especifica el formato de los datos enviados, pero ¿puedo enviarlo como objeto javascript?

Author: Gaurav Aggarwal, 2013-10-08

30 answers

Tuve el mismo problema usando asp.net MVC y encontraron la solución aquí

Hay mucha confusión entre los recién llegados a AngularJS en cuanto a por qué el $http funciones taquigráficas de servicio ($http.post(), etc.) no parece ser intercambiable con los equivalentes de jQuery (jQuery.post(), etc.)

La diferencia está en cómo jQuery y AngularJS serializar y transmitir los datos. Fundamentalmente, el problema radica en el idioma de su servidor de elección siendo incapaz de entender la transmisión de AngularJS de forma nativa ... Por defecto, jQuery transmite datos usando

Content-Type: x-www-form-urlencoded

Y la familiar foo=bar&baz=moe serialización.

AngularJS , sin embargo, transmite datos utilizando

Content-Type: application/json 

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

Serialización JSON, que desafortunadamente algunos lenguajes de servidor web - notablemente PHP-no unserialize de forma nativa.

Funciona como un encanto.

CÓDIGO

// 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-15 11:32:00

No está muy claro lo anterior, pero si está recibiendo la solicitud en PHP puede usar:

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

Para acceder a un array en PHP desde un POST de 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-03 01:14:30

Puede establecer el "Content-Type" predeterminado de esta manera:

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

Acerca del formato data:

El http http.post y http http.los métodos put aceptan cualquier valor de objeto JavaScript (o una cadena) como parámetro de datos. Si data es un objeto JavaScript, se convertirá, de forma predeterminada, a una cadena JSON.

Intenta usar esta variación

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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-24 19:40:51

He tenido un problema similar, y me pregunto si esto también puede ser útil: 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'}
})

Saludos,

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:38

Me gusta usar una función para convertir objetos a 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-04 14:30:21

Esto finalmente se ha abordado en angular 1.4 usando htt httpParamSerializerJQLike

Véase 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-10 16:25:33

Utilizo jQuery paramcon AngularJS post requrest. He aquí un ejemplo ... cree el módulo de aplicación AngularJS, donde myapp se define con ng-app en su código HTML.

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

Ahora vamos a crear un controlador de inicio de sesión y PUBLICAR correo electrónico y contraseña.

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

No me gusta explicar el código, es bastante simple de entender :) Tenga en cuenta que param es de jQuery, por lo que debe instalar tanto jQuery como AngularJS para que funcione. Aquí está un pantallazo.

introduzca la descripción de la imagen aquí

Espero que esto sea útil. ¡Gracias!

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-17 12:24:20

Tuve el mismo problema con AngularJS y Node.js + Express 4 + Router

El enrutador espera los datos de la solicitud de post en el cuerpo. Este cuerpo siempre estaba vacío si seguía el ejemplo de Angular Docs

Notación 1

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

Pero si lo usé en los datos

Notación 2

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

Editar 1:

De lo contrario nodo.el router js esperará los datos en req.cuerpo si se usa notación 1:

req.body.msg

Que también envía la información como carga JSON. Esto es mejor en algunos casos donde tiene matrices en su json y x-www-form-urlencoded le dará algunos problemas.

Funcionó. Espero que ayude.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-07 20:07:04

A diferencia de jQuery y por pedantería, Angular utiliza el formato JSON para POST data transfer from a client to the server (jQuery applies x-www-form-urlencoded presumably, although jQuery and Angular uses JSON for data imput). Por lo tanto, hay dos partes del problema: en la parte del cliente js y en la parte del servidor. Así que necesitas:

  1. Ponga la parte del cliente Angular de js de esta manera:

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

Y

  1. Escribir en la parte del servidor para recibir datos de un cliente (si es php).

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

Nota: $_POST no funcionará!

La solución funciona para mí bien, espero, y para usted.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-22 04:25:26

Para enviar datos a través de Post methode con $http de angularjs es necesario cambiar

data: "message=" + message, por 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-16 10:50:52

Para construir sobre la respuesta de @felipe-miosso:

  1. Descárgalo como un módulo AngularJS desde aquí ,
  2. Instalarlo
  3. Agrégalo a tu aplicación:

    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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-19 20:28:19

No tengo la reputación de comentar, pero en respuesta/además de la respuesta de Don F:

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

Se debe agregar un segundo parámetro de true a la función json_decode para devolver correctamente un array asociativo:

$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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-21 21:15:59

Angular

  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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-22 15:07:12

Este código resolvió el problema para mí. Es una solución a nivel de aplicación:

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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-27 15:21:55

Agregue esto en su archivo js:

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

Y añade esto a tu archivo de servidor:

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

Eso debería funcionar.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-22 13:16:16

También me enfrenté a un problema similar y estaba haciendo algo como esto y eso no funcionó. Mi controlador de resorte no fue capaz de leer el parámetro de datos.

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

Pero leyendo este foro y API Doc, intenté seguir camino y eso funcionó para mí. Si alguien también tiene un problema similar, Puede intentar a continuación también.

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

Por favor, compruebe https://docs.angularjs.org/api/ng/service / http http#post para lo que hace la configuración param. {data: '"id": "1"'} - Mapa de cadenas u objetos que se convertirá en 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-22 13:16:19

Esta es probablemente una respuesta tardía, pero creo que la forma más adecuada es utilizar la misma pieza de uso angular de código cuando se hace una solicitud "get" utilizando usted $httpParamSerializer tendrá que inyectarlo a su controlador así que simplemente puede hacer lo siguiente sin tener que usar Jquery en absoluto , $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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-24 18:20:25

En mi caso resuelvo el problema así:

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;

Necesita usar JSON.stringify para cada parámetro que contenga un objeto JSON y, a continuación, cree su objeto de datos con "$.param": -)

NB : Mi "objJSON" es un objeto JSON que contiene array, integer, string y contenido html. Su tamaño total es >3500 caracteres.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-28 11:07:05

Sé que tiene aceptadas contesta. Pero, seguir podría ayudar a futuros lectores, si la respuesta no les conviene por alguna razón.

Angular no hace ajax igual que jQuery. Mientras intentaba seguir la guía para modificar angular $httpprovider , encontré otros problemas. Por ejemplo, uso codeigniter en el que la función $this->input->is_ajax_request() siempre falla (que fue escrita por otro programador y utilizada globalmente, por lo que no puede cambiar) diciendo que esto no era una solicitud ajax real.

Para resolverlo, yo tomó ayuda de promesa diferida . Lo probé en Firefox, e ie9 y funcionó.

Tengo la siguiente función definida fuera cualquiera del código angular. Esta función hace que la llamada ajax jquery regular y devuelve diferido / promesa (todavía estoy aprendiendo) objeto.

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

Entonces lo llamo código angular usando el siguiente código. Tenga en cuenta que tenemos que actualizar el $scope manualmente usando $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!");
    });

Esto puede no ser el perfecto responder, pero me permitió usar llamadas jquery ajax con angular y me permitió actualizar el $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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-22 01:02:42

Tuve el mismo problema en express .. para resolver, debe usar bodyparser para analizar objetos json antes de enviar solicitudes 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-02 22:05:57

Estoy usando asp.net Servicios web WCF con angular js y código inferior trabajado:

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

Espero que ayude.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-20 14:39:52

No encontró un fragmento de código completo de cómo usar http http.método post para enviar datos al servidor y por qué no estaba funcionando en este caso.

Explicaciones del siguiente fragmento de código...

  1. Estoy usando jQuery $.función param para serializar los datos JSON a www post data
  2. Establecer el Content-Type en la variable de configuración que se pasará junto con la petición de AngularJS http http.mensaje que indica al servidor que estamos enviando datos en www post formato.

  3. Observe el htt htttp.método post, donde estoy enviando el 1er parámetro como url, el 2do parámetro como data (serializado) y el 3er parámetro como config.

El código restante se entiende por sí mismo.

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

Mira el ejemplo de código de http http.método post aquí .

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-11 03:54:14

Si está usando PHP esta es una manera fácil de acceder a un array en PHP desde una PUBLICACIÓN de AngularJS.

$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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-11 22:57:42

Si se usa Angular >= 1.4 , aquí está la solución más limpia utilizando el serializador proporcionado por 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';
});

Y luego simplemente puede hacer esto en cualquier lugar de su aplicación:

$http({
  method: 'POST',
  url: '/requesturl',
  data: {
    param1: 'value1',
    param2: 'value2'
  }
});

Y serializará correctamente los datos como param1=value1&param2=value2 y los enviará a /requesturl con el encabezado de tipo de contenido application/x-www-form-urlencoded; charset=utf-8 como se espera normalmente con las solicitudes POST en los endpoints.

TL; DR

Durante mi investigación encontré que la respuesta a este problema viene en muchos sabores diferentes; algunos son muy enrevesados y dependen de funciones personalizadas, algunos dependen de jQuery y algunos están incompletos al sugerir que solo necesita establecer el encabezado.

Si acaba de establecer el encabezado Content-Type, el punto final verá los datos POST, pero no estará en el formato estándar porque a menos que proporcione una cadena como su data, o serialice manualmente su objeto de datos, todo será serializado como JSON por defecto y puede ser interpretado incorrectamente en el punto final.

Por ejemplo, si el serializador correcto no se estableció en el ejemplo anterior, se vería en el punto final como:

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

Y eso puede llevar a un análisis inesperado, e. g. ASP.NET lo trata como un nombre de parámetro null, con {"param1":"value1","param2":"value2"} como valor; o Fiddler lo interpreta de la otra manera, con {"param1":"value1","param2":"value2"} como el nombre del parámetro, y null como el valor.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-18 09:46:57

Similar al formato de trabajo sugerido por el OP y la respuesta de Denison, excepto que usa $http.post en lugar de solo $http y sigue dependiendo de jQuery.

Lo bueno de usar jQuery aquí es que los objetos complejos se pasan correctamente; contra la conversión manual en parámetros de URL que pueden confundir los datos.

$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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-24 03:20:15

Cuando tuve este problema, el parámetro que estaba publicando resultó ser una matriz de objetos en lugar de un objeto simple.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-09 20:32:11

Acaba de actualizar de angular 1.2 a 1.3, han encontrado un problema en el código. Transformar un recurso conducirá a un bucle sin fin porque (creo) de la promise promesa de mantener de nuevo el mismo objeto. Tal vez ayude a alguien...

Podría arreglar eso por:

[...]
  /**
 * 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-03 19:06:41

He estado usando el código de la respuesta aceptada (el código de Felipe) por un tiempo y ha estado funcionando muy bien (¡gracias, Felipe!).

Sin embargo, recientemente descubrí que tiene problemas con objetos vacíos o matrices. Por ejemplo, al enviar este objeto:

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

PHP no parece ver B y C en absoluto. Se obtiene esto:

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

Un vistazo a la solicitud real en Chrome muestra esto:

A: 1
:
D: 2

Escribí un fragmento de código alternativo. Parece funcionar bien con mis casos de uso, pero No lo he probado extensivamente, así que úselo con precaución.

Usé TypeScript porque me gusta escribir fuerte, pero sería fácil convertirlo a JS puro:

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

Es menos eficiente que el código de Felipe, pero no creo que importe mucho, ya que debería ser inmediato en comparación con la sobrecarga general de la solicitud HTTP en sí.

Ahora PHP muestra:

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

Por lo que sé no es posible hacer que PHP reconozca que B. a y C son matrices vacías, pero al menos las claves aparecer, que es importante cuando hay código que se basa en una cierta estructura, incluso cuando su esencialmente vacío dentro.

También tenga en cuenta que convierte undefined s y null s en cadenas vacías.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-06 22:40:24

Resolví esto por debajo de los códigos:

Lado del cliente (Js):

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

Observe que los datos son un objeto.

En el servidor (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;
        }

Y 'AllowCrossSiteJsonAttribute' es necesario para las solicitudes de dominios cruzados:

public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*");
            base.OnActionExecuting(filterContext);
        }
    }

Espero que esto haya sido útil.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-23 11:04:46

No es culpa de angular. Angular está diseñado para trabajar en el mundo JSON. Así que cuando el servicio http http send AJAX request, envía todos sus datos como una carga útil, no como datos de formulario para que su aplicación backend pueda manejarlo. Pero jQuery hace algunas cosas internamente. Le indica al módulo aj ajax de jQuery que vincule los datos de formulario como JSON, pero antes de enviar la solicitud AJAX, se serializa JSON y agrega el encabezado application/x-www-form-urlencoded. De esta manera su aplicación backend capaz de recibir datos de formulario en forma de parámetros post y no JSON.

Pero puede modificar el comportamiento predeterminado del servicio angular http http mediante

  1. Añadiendo encabezado
  2. Serializar json

Htt httpParamSerializerJQLike es el servicio integrado de angular que serializa json de la misma manera$.el param hace de jQuery.

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

Si necesita un complemento para serializar los datos de formulario en JSON primero, use este 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-29 12:35:40