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

337

¿Alguien podría decirme por qué la siguiente declaración no envía los datos de la publicación a la URL designada? La url se llama 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 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 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?

Spencer Mark
fuente
¿La URL tiene el mismo origen?
fmquaglia
Lo sentimos - sí para todos los ejemplos es la misma url
Spencer Marcos
@SpencerMark lo siento ... intenté por encima de tu código de trabajo ... no funciona para mí.
Arul Sidthan

Respuestas:

346

Tuve el mismo problema usando 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 jQuery ( jQuery.post(), etc.)

La diferencia está en cómo jQuery y AngularJS serializan y transmiten los datos. Básicamente, el problema radica en que el idioma de elección de su servidor es incapaz de comprender la transmisión de AngularJS de forma nativa ... Por defecto, jQuery transmite datos utilizando

Content-Type: x-www-form-urlencoded

y la foo=bar&baz=moeserialización familiar .

AngularJS , sin embargo, transmite datos usando

Content-Type: application/json 

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

La serialización JSON, que desafortunadamente algunos lenguajes de 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<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
fuente
77
He agregado este script a Bower, utilizo bower install angular-post-fix --save-devpara agregarlo.
Billy Blaze
Entonces, ¿hay alguna manera de cambiar el método de transmisión de datos de PHP? Porque ese es el problema que estoy teniendo actualmente.
Demodave el
1
Este código funciona muy bien en su mayor parte, pero he tenido problemas al enviar una jerarquía de objetos vacíos o incluso valores vacíos. Por ejemplo, {a: 1, b: {c: {d: {}}}, e: undefined, f: null, g: 2} no se codificarán correctamente y PHP lo obtendrá como ["a" = > "1", "g" => "2"]. Se perdería toda la estructura bajo "b", así como "e" y "f", incluidas las teclas mismas. Publiqué un código alternativo a continuación, con el que la estructura anterior se decodifica como: ["a" => "1", "b" => ["c" => ["d" => ""]], "e" => "", "f" => "", "g" => "2"].
obe
1
¿Cómo debo implementar esto para multipart / form-data?
davidlee
Excelente :) De hecho, funcionó como un encanto.
Enfrenté
115

No está muy 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 un AngularJS POST.

Don F
fuente
3
Necesitaba agregar true para forzarlo a una matriz al sobrescribir la matriz $ _POST con ella. json_decode(file_get_contents('php://input'), true);
Jon
44
@Zalaboza, estaría de acuerdo en que es difícil tener una solución considerada 'universal', pero no estoy de acuerdo en que sea 'hacky' --- php.net afirma: "file_get_contents () es la forma preferida de leer el contenido de un archivo en una cadena. Utilizará técnicas de mapeo de memoria si es compatible con su sistema operativo para mejorar el rendimiento ". Por supuesto, no estamos leyendo un archivo en esta situación, pero estamos leyendo datos json publicados. Sería genial si pudiera aportar una nueva respuesta o proporcionar nueva información para ayudar a los lectores (incluido yo mismo) a tomar una mejor decisión al respecto.
Don F
78

Puede establecer 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á, por defecto, 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
fuente
99
No parece funcionar. Acabo de probar la variación con los datos como cadena y: encabezados: {'Content-Type': 'application / x-www-form-urlencoded'}, y parece funcionar, pero hay una mejor manera de hacerlo ¿eso?
Spencer Mark
2
Establezca el tipo de contenido predeterminado como se describió anteriormente y para los datos no use el objeto js. Use una cadena como esta: 'message =' + message funciona para mí
gSorry
58

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,

ericson.cepeda
fuente
Parece que los encabezados fueron el único cambio que necesitábamos. ¡Gracias!
Ben Guthrie
Gracias, eso lo hizo por mí :) El problema era la codificación de los datos POST.
Daan
33

Me gusta usar una función para convertir objetos para publicar parámetros.

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
fuente
30

Esto finalmente se ha abordado en 1.4 angular usando $ httpParamSerializerJQLike

Ver 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'
})})
Stetzon
fuente
Estoy enfrentando el problema POST 192.168.225.75:7788/procure/p/search 400 (Solicitud incorrecta)
Anuj
19

Yo uso jQuery param con AngularJS post requrest. Aquí hay un ejemplo ... cree el módulo de aplicación AngularJS, donde myappse define con ng-appsu código HTML.

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

Ahora permítanos crear un controlador de inicio de sesión y enviar 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 parames de jQuery, por lo que debe instalar jQuery y AngularJS para que funcione. Aquí hay una captura de pantalla.

ingrese la descripción de la imagen aquí

Espero que esto sea útil. ¡Gracias!

Madan Sapkota
fuente
10

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

El enrutador 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 usa la notación 1:

req.body.msg

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

funcionó. Espero eso ayude.

Alcnows
fuente
10

A diferencia de JQuery y por el bien de la pedantería, Angular usa el formato JSON para la transferencia de datos POST de un cliente al servidor (JQuery aplica x-www-form-urlencoded presumiblemente, aunque JQuery y Angular usan JSON para la entrada de datos). 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. poner parte del cliente angular js así:

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

Y

  1. escriba en la parte de su 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 bien para mí, con suerte, y para ti.

romano
fuente
8

Para enviar datos a través del método Post con $httpangularjs, debe cambiar

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

BERGUIGA Mohamed Amine
fuente
1
¿Por qué se requieren datos: $ .param al enviar datos de publicación de AngularJS?
cielo azul
7

Para construir sobre la respuesta de @ felipe-miosso:

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

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

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 truedebe agregar un segundo parámetro de a la json_decodefunción para devolver correctamente una matriz asociativa:

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

Esten
fuente
6

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();
        }
Malcolm Swaine
fuente
5

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";
  }
]);
Spartak Lalaj
fuente
5

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.

Jesus Erwin Suarez
fuente
4

También enfrenté un problema similar y estaba haciendo algo como esto y eso no funcionó. Mi controlador 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, intenté seguirlo y funcionó para mí. Si alguien también tiene un problema similar, también puede intentarlo a continuación.

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

Consulte https://docs.angularjs.org/api/ng/service/ $ http # post para saber qué hace param config. {data: '"id": "1"'} - Mapa de cadenas u objetos que se convertirán en URL? data = "id: 1"

Viraj
fuente
4

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", $httpParamSerializertendrá que inyectarlo en su controlador para que 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}));
}
onePeggedChicken
fuente
4

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;

Debe usar JSON.stringify para cada parámetro que contiene un objeto JSON y luego construir su objeto de datos con "$ .param" :-)

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

bArraxas
fuente
3

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

Angular no hace ajax lo mismo que jQuery. Mientras intentaba seguir la guía para modificar angular $httpprovider, encontré otros problemas. Por ejemplo, uso codeigniter en el que la $this->input->is_ajax_request()función siempre fallaba (que fue escrita por otro programador y utilizada 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 realiza una llamada regular 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 el $scopemanual 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 llamadas jquery ajax con angular y me permitió actualizar el $scope.

Nis
fuente
2
Angular tiene su propio servicio de promesas llamado $ q desde 1.3. No es necesario usar JQuery para una publicación.
mbokil
3

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

app.use(bodyParser.json());
Muhammad Soliman
fuente
3

Estoy usando asp.net WCF webservices con angular js y el siguiente código funcionó:

 $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.

Mehdi Rostami
fuente
3

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 los datos de publicación de www
  2. Establecer el tipo de contenido en la variable de configuración que se pasará junto con la solicitud de angularJS $ http.post que le indica al servidor que estamos enviando datos en formato de publicación 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 a 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 del método $ http.post aquí .

Sheo Narayan
fuente
3

Si usa 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);
Luis Felipe Barnett V
fuente
3

Si usa Angular> = 1.4 , esta es la solución más limpia que usa 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 puedes hacer esto en cualquier lugar de tu aplicación:

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

Y serializará correctamente los datos param1=value1&param2=value2y los enviará /requesturlcon el application/x-www-form-urlencoded; charset=utf-8encabezado Content-Type como normalmente se espera con las solicitudes POST en los puntos finales.

TL; DR

Durante mi investigación descubrí 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 algunos son incompletos al sugerir que solo necesita establecer el encabezado.

Si solo establece el Content-Typeencabezado, 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 predeterminado y puede interpretarse incorrectamente en el punto final.

por ejemplo, si el serializador correcto no se configuró en el ejemplo anterior, se vería 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 nullnombre de parámetro, con un {"param1":"value1","param2":"value2"}valor; o Fiddler lo interpreta de otra manera, con {"param1":"value1","param2":"value2"}el nombre del parámetro y nullel valor.

Saeb Amini
fuente
3

Similar al formato de trabajo sugerido por el OP y la respuesta de Denison, excepto el uso en $http.postlugar de solo $httpy todavía 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 confundir los datos.

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

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

D. Kermott
fuente
2

Recién actualizado de angular 1.2 a 1.3, he encontrado un problema en el código. La transformación de un recurso conducirá a un bucle sin fin porque (creo) que la promesa de $ retiene el mismo objeto. Tal vez ayude a alguien ...

Podría arreglar eso de la siguiente manera:

[...]
  /**
 * 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) {
[...]
tom_w
fuente
2

He estado usando el código de respuesta aceptado (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 pone 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 exhaustivamente, así que úselo con precaución.

Usé TypeScript porque me gusta la escritura fuerte pero sería fácil convertir 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.

Ahora PHP muestra:

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

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

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

obe
fuente
¡TypeScript es la mejor manera de codificar en POO con JavaScript!
Desfigurar el
2

Simplemente ponga los datos que desea enviar como segundo parámetro:

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

Otra forma que también funciona es:

$http.post('request-url',  { params: { paramName: value } });

Asegúrese de que paramNamecoincida exactamente con el nombre del parámetro de la función que está llamando.

Fuente: método de acceso directo posterior a AngularJS

Marco Lackovic
fuente
55
¿Alguien puede explicar por qué esta respuesta ha sido rechazada?
Marco Lackovic
1
No hay forma de que esta solución sea rechazada, es la más simple, corta y probada en la documentación angular docs.angularjs.org/api/ng/service/$http
ainasiart
1

Resolví esto con 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);
    ......

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 solicitudes de dominio cruzado:

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.

pixparker
fuente