AngularJs $ http.post () no envía datos

¿Alguien podría decirme por qué la siguiente statement no envía los datos de la publicación a la URL designada? Se llama a la url pero en el servidor cuando imprimo $ _POST – obtengo una matriz vacía. Si imprimo un mensaje en la consola antes de agregarlo a los datos, muestra el contenido correcto.

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

También lo intenté con los datos como una 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 alguna manera de hacerlo con $ 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?

Tuve el mismo problema al usar asp.net MVC y encontré la solución aquí

Existe mucha confusión entre los recién llegados a AngularJS sobre por qué las funciones de taquigrafía del servicio $http ( $http.post() , etc.) no parecen intercambiables con los equivalentes jQuery ( jQuery.post() , etc.)

La diferencia está en cómo jQuery y AngularJS serializan y transmiten los datos. Fundamentalmente, el problema radica en que el idioma de elección del servidor no puede comprender la transmisión de AngularJS de forma nativa … De forma predeterminada, jQuery transmite datos usando

 Content-Type: x-www-form-urlencoded 

y la conocida serialización foo=bar&baz=moe .

AngularJS , sin embargo, transmite datos usando

 Content-Type: application/json 

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

La serialización JSON, que desafortunadamente algunos lenguajes del servidor web, especialmente PHP, no se deserializan de forma nativa.

Funciona de maravilla.

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 

No está súper claro arriba, pero si está recibiendo la solicitud en PHP puede usar:

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

Para acceder a una matriz en PHP desde una POST AngularJS.

Puede establecer el “Tipo de contenido” predeterminado de esta manera:

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

Sobre el formato de data :

Los métodos $ http.post y $ http.put aceptan cualquier valor de objeto JavaScript (o una cadena) como su parámetro de datos. Si los datos son un objeto JavaScript, se convertirán, de manera predeterminada, en 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 }); } 

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,

Me gusta usar una función para convertir objetos a postear 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'} }) 

Esto finalmente se ha abordado en angular 1.4 utilizando $ httpParamSerializerJQLike

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

 .controller('myCtrl', function($http, $httpParamSerializerJQLike) { $http({ method: 'POST', url: baseUrl, data: $httpParamSerializerJQLike({ "user":{ "email":"wahxxx@gmail.com", "password":"123456" } }), headers: 'Content-Type': 'application/x-www-form-urlencoded' })}) 

Yo uso jQuery param con AngularJS post requrest. Aquí hay un ejemplo … crear 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 permítanos crear un controlador de inicio de sesión y correo electrónico POST 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 exagerar el código, es lo suficientemente simple de entender 🙂 Tenga en cuenta que param es de jQuery, por lo que debe instalar jQuery y AngularJS para que funcione. Aquí hay una captura de pantalla.

enter image description here

Espero que esto sea útil. ¡Gracias!

A diferencia de JQuery y en aras de la pedantería, Angular utiliza el formato JSON para la transferencia de datos POST de un cliente al servidor (JQuery aplica x-www-form-urlencoded, aunque JQuery y Angular usan JSON para datos incorrectos). Por lo tanto, hay dos partes del problema: en la parte del cliente js y en la parte del servidor. Así que tú necesitas:

  1. ponga js Angular client part como este:

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

Y

  1. escriba en su 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 me funciona bien, con suerte y para ti.

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

Router espera los datos de la solicitud de la publicación 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, el enrutador node.js esperará los datos en req.body si se utiliza la notación 1:

 req.body.msg 

Que también envía la información como carga útil JSON. Esto es mejor en algunos casos donde tienes arreglos en json y x-www-form-urlencoded te dará algunos problemas.

funcionó. Espero eso ayude.

Para enviar datos a través de Post methode con $http de angularjs, debe cambiar

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

Para construir sobre la respuesta de @ felipe-miosso:

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

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

No tengo la reputación de comentar, pero en respuesta / adición a 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 una matriz asociativa:

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

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

Este código resolvió el problema para mí. Es una solución de 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"; } ]); 

Agregue esto en su archivo js:

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

y agregue esto a su archivo de servidor:

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

Eso debería funcionar.

También enfrenté un problema similar y estaba haciendo algo como esto y eso no funcionó. El controlador My Spring no pudo leer el parámetro de datos.

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

Pero al leer este foro y API Doc, traté de seguirlo y me funcionó. Si alguien también tiene un problema similar, también puedes probarlo abajo.

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

Por favor, consulte https://docs.angularjs.org/api/ng/service/ $ http # post para ver qué configuración de param hace. {data: ‘”id”: “1”‘} – Mapa de cadenas u objetos que se convertirán en URL? data = “id: 1”

esta es probablemente una respuesta tardía, pero creo que la forma más adecuada es usar el mismo código de uso angular al hacer una solicitud de “obtención” usando $httpParamSerializer tendrá que inyectarlo a su controlador para que simplemente pueda 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})); } 

En mi caso, resuelvo el problema de esta manera:

 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 luego comstackr su objeto de datos con “$ .param” 🙂

NB: Mi “objJSON” es un objeto JSON que contiene matriz, entero, cadena y contenido html. Su tamaño total es> 3500 caracteres.

Sé que ha aceptado la respuesta. Pero, el seguimiento puede ayudar a los lectores futuros, si la respuesta no les conviene por alguna razón.

Angular no hace ajax igual que jQuery. Mientras traté de seguir la guía para modificar $httpprovider angular, me encontré con otros problemas. Por ejemplo, uso codeigniter en el que la función $this->input->is_ajax_request() siempre falló (que fue escrita por otro progtwigdor y se usó globalmente, por lo que no puedo cambiar) diciendo que esta no era una solicitud real de AJAX.

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

Tengo la siguiente función definida fuera de cualquiera de los códigos angulares. Esta función hace una llamada regular de jquery ajax y devuelve el objeto diferido / promesa (todavía estoy aprendiendo).

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

Puede que esta no sea la respuesta perfecta, pero me permitió usar las llamadas jquery ajax con angular y me permitió actualizar $scope .

Tuve el mismo problema en express. Para resolverlo, debe usar bodyparser para analizar los objetos json antes de enviar solicitudes http.

 app.use(bodyParser.json()); 

Estoy usando los servicios web asp.net WCF con js angulares y debajo del código 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 eso ayude.

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

Explicaciones del fragmento de código a continuación …

  1. Estoy usando la función jQuery $ .param para serializar los datos JSON en www datos de la publicación
  2. Establecer el tipo de contenido en la variable de configuración que se pasará junto con la solicitud de angularJS $ http.post que indica al servidor que estamos enviando datos en formato www.

  3. Observe el método $ htttp.post, donde estoy enviando el primer parámetro como url, el segundo parámetro como datos (serializados) y el tercer 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 + "
status: " + status + "
headers: " + header + "
config: " + config; }); };

Mire el ejemplo de código del método $ http.post aquí .

Si usa Angular> = 1.4 , aquí está la solución más limpia usando el serializador provisto 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 puedes simplemente hacer esto en cualquier lugar de tu aplicación:

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

Y serializará correctamente los datos como param1=value1&param2=value2 y lo enviará a /requesturl con la application/x-www-form-urlencoded; charset=utf-8 application/x-www-form-urlencoded; charset=utf-8 Content-Type header como normalmente se espera con solicitudes POST en puntos finales.

TL; DR

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

Si solo configura 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 sus 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 configuró en el ejemplo anterior, se verá en el punto final como:

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

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

Similar al formato de trabajo sugerido de OP y la respuesta de Denison, excepto que usa $http.post lugar de solo $http y aún depende 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 distorsionar los datos.

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

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

Recién actualizado de angular 1.2 a 1.3, ha encontrado un problema en el código. Transformar un recurso conducirá a un ciclo infinito porque (creo) de $ promete mantener nuevamente el mismo objeto. Tal vez ayudará 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) { [...] 

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

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

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

PHP no parece ver B y C en absoluto. Se consigue 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.

Utilicé 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 ($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 debe ser inmediato en comparación con la sobrecarga general de la solicitud HTTP.

Ahora PHP muestra:

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

Por lo que sé, no es posible hacer que PHP reconozca que Ba y C son matrices vacías, pero al menos aparecen las teclas, lo cual es importante cuando hay un código que se basa en cierta estructura incluso cuando está esencialmente vacío por dentro.

También tenga en cuenta que convierte s indefinidos y nulos en cadenas vacías.

Si usas PHP, esta es una manera fácil de acceder a una matriz en PHP desde un POST AngularJS.

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

Lo resolví por los siguientes 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); ...... 

Note que los datos son un objeto.

En el servidor (ASP.NET MVC):

 [AllowCrossSiteJson] public string Api() { var data = JsonConvert.DeserializeObject(Request.Form[0]); if (data == null) return "Null Request"; var bl = Page.Bl = new Core(this); return data.methodName; } 

y ‘AllowCrossSiteJsonAttribute’ es necesario para 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.

No es culpa de angular. Angular está diseñado para funcionar en el mundo JSON. Entonces, cuando el servicio $ http envía una solicitud AJAX, envía todos sus datos como una carga, no como datos de formulario para que su aplicación de fondo pueda manejarlo. Pero jQuery hace algunas cosas internamente. Usted instruye al módulo $ ajax de jQuery para enlazar datos de formulario como JSON, pero antes de enviar la solicitud AJAX, serializó JSON y application/x-www-form-urlencoded encabezado application/x-www-form-urlencoded . De esta forma, su aplicación de fondo puede recibir datos de formulario en forma de parámetros posteriores y no JSON.

Pero puede modificar el comportamiento predeterminado del $ angular del servicio http por

  1. Agregar encabezado
  2. Serialización json

$ httpParamSerializerJQLike es el servicio incorporado de angular que serializa json de la misma manera que $ .param lo 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 datos de formulario en JSON primero, use este https://github.com/marioizquierdo/jquery.serializeJSON