Question Comment puis-je publier des données sous forme de données de formulaire au lieu d'une charge utile de demande?


Dans le code ci-dessous, l'AngularJS $http method appelle l'URL et soumet l'objet xsrf en tant que "Request Payload" (comme décrit dans l'onglet réseau du débogueur Chrome). Le jQuery $.ajax méthode fait le même appel, mais soumet xsrf en tant que "données de formulaire".

Comment puis-je soumettre xsrf à AngularJS en tant que données de formulaire au lieu d'une charge utile de requête?

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


origine


Réponses:


La ligne suivante doit être ajoutée à l'objet $ http transmis:

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

Et les données transmises doivent être converties en une chaîne encodée en URL:

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

Donc, vous avez quelque chose comme:

$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

METTRE À JOUR

Pour utiliser les nouveaux services ajoutés avec AngularJS V1.4, voir


591
2017-07-11 23:31



Si vous ne voulez pas utiliser jQuery dans la solution, vous pouvez essayer cela. Solution retirée d'ici 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 confusion persistante autour de cette question m'a inspiré à écrire un article sur le blog. La solution que je propose dans ce post est meilleure que votre solution actuelle la mieux notée car elle ne vous limite pas à paramétrer votre objet de données pour les appels de service $ http; c'est-à-dire avec ma solution, vous pouvez simplement continuer à transmettre des objets de données réels à $ http.post (), etc. et obtenir le résultat souhaité.

En outre, la réponse la mieux notée repose sur l'inclusion de jQuery complet dans la page pour la fonction $ .param (), alors que ma solution est agnostique jQuery, pure AngularJS prête.

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

J'espère que cela t'aides.


91
2017-12-21 12:07



J'ai pris quelques-unes des autres réponses et fait quelque chose un peu plus propre, mettez ceci .config() appelez à la fin de votre angular.module dans votre 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



À partir de AngularJS v1.4.0, il y a un $httpParamSerializer service qui convertit n'importe quel objet en une partie d'une requête HTTP selon les règles listées sur le page docs.

Il peut être utilisé comme ceci:

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

Rappelez-vous que pour un poste correct, le Content-Type l'en-tête doit être changé. Pour le faire globalement pour toutes les requêtes POST, ce code (tiré de la demi-réponse d'Albireo) peut être utilisé:

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

Pour ce faire seulement pour le poste actuel, le headers la propriété de l'objet-de-requête doit être modifiée:

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



Vous pouvez définir le comportement globalement:

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

Vous n'avez donc pas à le redéfinir à chaque fois:

$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



Pour contourner le problème, vous pouvez simplement faire en sorte que le code recevant le POST réponde aux données de l'application / json. Pour PHP, j'ai ajouté le code ci-dessous, ce qui me permet d'y mettre un POST soit en format codé, soit en format 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



Ces réponses semblent démesurées, parfois simples:

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

15
2018-03-24 09:19



Vous pouvez essayer avec la solution ci-dessous

$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



Créez un service d'adaptateur pour la publication:

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'}
        })
    }

}) 

Utilisez-le dans vos contrôleurs ou autre:

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



Il y a un très bon tutoriel qui passe en revue ceci et d'autres choses liées - Soumission de formulaires AJAX: la méthode AngularJS.

Fondamentalement, vous devez définir l'en-tête de la requête POST pour indiquer que vous envoyez des données de formulaire sous la forme d'une chaîne codée par URL et définir les données à envoyer au même format

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

Notez que la fonction auxiliaire param () de jQuery est utilisée ici pour sérialiser les données dans une chaîne, mais vous pouvez également le faire manuellement si vous n'utilisez pas jQuery.


7
2017-07-02 12:33