Pregunta ¿Cómo puedo publicar datos como datos de formulario en lugar de una carga de solicitud?


En el código a continuación, el AngularJS $http método llama a la URL y envía el objeto xsrf como "Solicitud de carga útil" (como se describe en la pestaña de la red del depurador de Chrome). El jQuery $.ajax método hace la misma llamada, pero envía xsrf como "Datos del formulario".

¿Cómo puedo hacer que AngularJS envíe xsrf como datos de formulario en lugar de una carga de solicitud?

var url = 'http://somewhere.com/';
var xsrf = {fkey: 'xsrf key'};

$http({
    method: 'POST',
    url: url,
    data: xsrf
}).success(function () {});

$.ajax({
    type: 'POST',
    url: url,
    data: xsrf,
    dataType: 'json',
    success: function() {}
});

502
2017-07-11 22:44


origen


Respuestas:


La siguiente línea debe agregarse al objeto $ http que se pasa:

headers: {'Content-Type': 'application/x-www-form-urlencoded'}

Y los datos pasados ​​deben convertirse a una cadena codificada en URL:

> $.param({fkey: "key"})
'fkey=key'

Entonces tienes algo como:

$http({
    method: 'POST',
    url: url,
    data: $.param({fkey: "key"}),
    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})

De: https://groups.google.com/forum/#!msg/angular/5nAedJ1LyO0/4Vj_72EZcDsJ

ACTUALIZAR

Para usar los nuevos servicios agregados con AngularJS V1.4, consulte


591
2017-07-11 23:31



Si no desea usar jQuery en la solución, puede intentarlo. Solución atrapada de aquí https://stackoverflow.com/a/1714899/1784301

$http({
    method: 'POST',
    url: url,
    headers: {'Content-Type': 'application/x-www-form-urlencoded'},
    transformRequest: function(obj) {
        var str = [];
        for(var p in obj)
        str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
        return str.join("&");
    },
    data: xsrf
}).success(function () {});

192
2018-02-14 06:04



La continua confusión en torno a este tema me inspiró a escribir una publicación en un blog sobre el tema. La solución que propongo en esta publicación es mejor que su solución actual mejor valorada porque no lo limita a parametrizar su objeto de datos para llamadas de servicio $ http; es decir, con mi solución simplemente puede continuar pasando objetos de datos reales a $ http.post (), etc. y aún así lograr el resultado deseado.

Además, la respuesta mejor clasificada se basa en la inclusión de jQuery completo en la página para la función $ .param (), mientras que mi solución es jQuery agnostic, pura AngularJS ready.

http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/

Espero que esto ayude.


91
2017-12-21 12:07



Tomé algunas de las otras respuestas e hice algo un poco más limpio, pon esto .config() llama al final de tu angular.module en tu app.js:

.config(['$httpProvider', function ($httpProvider) {
  // Intercept POST requests, convert to standard form encoding
  $httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
  $httpProvider.defaults.transformRequest.unshift(function (data, headersGetter) {
    var key, result = [];

    if (typeof data === "string")
      return data;

    for (key in data) {
      if (data.hasOwnProperty(key))
        result.push(encodeURIComponent(key) + "=" + encodeURIComponent(data[key]));
    }
    return result.join("&");
  });
}]);

82
2017-10-28 11:39



A partir de AngularJS v1.4.0, hay un built-in $httpParamSerializer servicio que convierte cualquier objeto en una parte de una solicitud HTTP de acuerdo con las reglas que se enumeran en el página de documentos.

Se puede usar así:

$http.post('http://example.com', $httpParamSerializer(formDataObj)).
    success(function(data){/* response status 200-299 */}).
    error(function(data){/* response status 400-999 */});

Recuerde que para una publicación correcta, la Content-Type encabezado debe ser cambiado. Para hacer esto globalmente para todas las solicitudes POST, se puede usar este código (tomado de la mitad de respuesta de Albireo):

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

Para hacer esto solo para la publicación actual, la headers la propiedad del objeto de solicitud debe modificarse:

var req = {
 method: 'POST',
 url: 'http://example.com',
 headers: {
   'Content-Type': 'application/x-www-form-urlencoded'
 },
 data: $httpParamSerializer(formDataObj)
};

$http(req);

57
2018-06-01 19:57



Puedes definir el comportamiento globalmente:

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

De modo que no tiene que redefinirlo cada vez:

$http.post("/handle/post", {
    foo: "FOO",
    bar: "BAR"
}).success(function (data, status, headers, config) {
    // TODO
}).error(function (data, status, headers, config) {
    // TODO
});

24
2017-11-21 09:32



Como solución alternativa, puede hacer que el código que recibe el mensaje POST responda a los datos de la aplicación / json. Para PHP agregué el código a continuación, lo que me permite POSTAR en forma codificada o JSON.

//handles JSON posted arguments and stuffs them into $_POST
//angular's $http makes JSON posts (not normal "form encoded")
$content_type_args = explode(';', $_SERVER['CONTENT_TYPE']); //parse content_type string
if ($content_type_args[0] == 'application/json')
  $_POST = json_decode(file_get_contents('php://input'),true);

//now continue to reference $_POST vars as usual

20
2017-11-08 22:57



Estas respuestas parecen una locura exagerada, a veces, lo simple es simplemente mejor:

$http.post(loginUrl, "userName=" + encodeURIComponent(email) +
                     "&password=" + encodeURIComponent(password) +
                     "&grant_type=password"
).success(function (data) {
//...

15
2018-03-24 09:19



Puedes probar con la siguiente solución

$http({
        method: 'POST',
        url: url-post,
        data: data-post-object-json,
        headers: {'Content-Type': 'application/x-www-form-urlencoded'},
        transformRequest: function(obj) {
            var str = [];
            for (var key in obj) {
                if (obj[key] instanceof Array) {
                    for(var idx in obj[key]){
                        var subObj = obj[key][idx];
                        for(var subKey in subObj){
                            str.push(encodeURIComponent(key) + "[" + idx + "][" + encodeURIComponent(subKey) + "]=" + encodeURIComponent(subObj[subKey]));
                        }
                    }
                }
                else {
                    str.push(encodeURIComponent(key) + "=" + encodeURIComponent(obj[key]));
                }
            }
            return str.join("&");
        }
    }).success(function(response) {
          /* Do something */
        });

9
2017-10-09 11:00



Crea un servicio de adaptador para la publicación:

services.service('Http', function ($http) {

    var self = this

    this.post = function (url, data) {
        return $http({
            method: 'POST',
            url: url,
            data: $.param(data),
            headers: {'Content-Type': 'application/x-www-form-urlencoded'}
        })
    }

}) 

Úselo en sus controladores o lo que sea:

ctrls.controller('PersonCtrl', function (Http /* our service */) {
    var self = this
    self.user = {name: "Ozgur", eMail: null}

    self.register = function () {
        Http.post('/user/register', self.user).then(function (r) {
            //response
            console.log(r)
        })
    }

})

8
2018-05-16 23:41



Hay un tutorial realmente bueno que repasa esta y otras cosas relacionadas: Envío de formularios AJAX: The AngularJS Way.

Básicamente, debe configurar el encabezado de la solicitud POST para indicar que está enviando datos del formulario como una cadena codificada en la URL, y establecer que los datos se envíen con el mismo formato.

$http({
  method  : 'POST',
  url     : 'url',
  data    : $.param(xsrf),  // pass in data as strings
  headers : { 'Content-Type': 'application/x-www-form-urlencoded' }  // set the headers so angular passing info as form data (not request payload)
});

Tenga en cuenta que la función auxiliar de jQuery param () se usa aquí para serializar los datos en una cadena, pero también puede hacerlo manualmente si no se usa jQuery.


7
2017-07-02 12:33