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

Resuelto Spencer Mark asked hace 10 años • 37 respuestas

¿Alguien podría decirme por qué la siguiente declaración 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, aparece 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 probé 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 alguna forma de hacerlo con $http.post()? ¿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 enviarlos como un objeto javascript?

Spencer Mark avatar Oct 09 '13 00:10 Spencer Mark
Aceptado

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 $httpfunciones abreviadas del servicio ( $http.post(), etc.) no parecen ser intercambiables con los equivalentes de jQueryjQuery.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 su servidor elegido 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 familiar foo=bar&baz=moeserialización.

AngularJS , sin embargo, transmite datos usando

Content-Type: application/json 

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

Serialización JSON, que desafortunadamente algunos lenguajes de servidores web, especialmente PHP , no 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<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;
  }];
});
Felipe Miosso avatar Nov 29 '2013 00:11 Felipe Miosso

No está muy claro arriba, pero si recibes la solicitud en PHP puedes usar:

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

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

Don F avatar Oct 27 '2014 16:10 Don F

Puede configurar el "Tipo de contenido" predeterminado de esta manera:

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

Sobre el dataformato:

Los métodos $http.post y $http.put aceptan cualquier valor de objeto JavaScript (o una cadena) como parámetro de datos. Si los datos son un objeto JavaScript, se convertirán, de forma 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
    });
}
Denison Luz avatar Oct 08 '2013 17:10 Denison Luz

Tuve 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,

ericson.cepeda avatar May 31 '2014 03:05 ericson.cepeda

Me gusta usar una función para convertir objetos a parámetros de publicación.

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'}
})
Rômulo Collopy avatar Aug 29 '2014 14:08 Rômulo Collopy