web-dev-qa-db-fra.com

Comment je POST _> données de formulaire encodées avec $ http sans jQuery?

Je suis nouveau sur AngularJS, et pour commencer, je pensais développer une nouvelle application utilisant uniquement AngularJS.

J'essaie de passer un appel AJAX au serveur, en utilisant $http à partir de mon Angular App.

Pour envoyer les paramètres, j'ai essayé ce qui suit:

$http({
    method: "post",
    url: URL,
    headers: {'Content-Type': 'application/x-www-form-urlencoded'},
    data: $.param({username: $scope.userName, password: $scope.password})
}).success(function(result){
    console.log(result);
});

Cela fonctionne, mais jQuery est également utilisé à $.param. Pour supprimer la dépendance sur jQuery, j'ai essayé:

data: {username: $scope.userName, password: $scope.password}

mais cela a semblé échouer. Puis j'ai essayé params:

params: {username: $scope.userName, password: $scope.password}

mais cela aussi semblait échouer. Puis j'ai essayé JSON.stringify:

data: JSON.stringify({username: $scope.userName, password: $scope.password})

J'ai trouvé ces réponses possibles à ma quête, mais sans succès. Est-ce que je fais quelque chose de mal? Je suis sûr que AngularJS fournirait cette fonctionnalité, mais comment?

189
Veer Shrivastav

Je pense que vous devez faire est de transformer vos données d'objet non pas en chaîne JSON, mais en paramètres url.

Du blog de Ben Nadel .

Par défaut, le service $ http transformera la demande sortante en sérialisant les données au format JSON, puis en les publiant avec le type de contenu "application/json". Lorsque nous voulons publier la valeur en tant que publication FORM, nous devons modifier l'algorithme de sérialisation et publier les données avec le type de contenu "application/x-www-form-urlencoded".

Exemple à partir d'ici .

$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: {username: $scope.userName, password: $scope.password}
}).then(function () {});

MISE À JOUR

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

403
allenhwkim

Variables de codage d'URL utilisant uniquement les services AngularJS

Avec AngularJS 1.4 et versions ultérieures, deux services peuvent gérer le processus de codage des données d’URL pour les demandes POST, éliminant ainsi la nécessité de manipuler les données avec transformRequest ou d’utiliser des dépendances externes telles que jQuery:

  1. $httpParamSerializerJQLike - un sérialiseur inspiré par jQuery .param() ( recommandé )

  2. $httpParamSerializer - un sérialiseur utilisé par Angular lui-même pour les demandes GET

Exemple d'utilisation

_$http({
  url: 'some/api/endpoint',
  method: 'POST',
  data: $httpParamSerializerJQLike($scope.appForm.data), // Make sure to inject the service you choose to the controller
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded' // Note the appropriate header
  }
}).then(function(response) { /* do something here */ });
_

Voir une démonstration plus détaillée de Plunker


En quoi _$httpParamSerializerJQLike_ et _$httpParamSerializer_ sont-ils différents?

En général, il semble que _$httpParamSerializer_ utilise moins de format de codage d'URL "traditionnel" que _$httpParamSerializerJQLike_ lorsqu'il s'agit de structures de données complexes.

Par exemple (en ignorant le pourcentage d'encodage des crochets):

Encodage d'un tablea

_{sites:['google', 'Facebook']} // Object with array property

sites[]=google&sites[]=facebook // Result with $httpParamSerializerJQLike

sites=google&sites=facebook // Result with $httpParamSerializer
_

Encodage d'un objet

_{address: {city: 'LA', country: 'USA'}} // Object with object property

address[city]=LA&address[country]=USA // Result with $httpParamSerializerJQLike

address={"city": "LA", country: "USA"} // Result with $httpParamSerializer
_
136
Boaz

Tout cela ressemble à de l'overkill (ou ne fonctionne pas) ... faites ceci:

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

Le problème est le format de chaîne JSON. Vous pouvez utiliser une simple chaîne d'URL dans les données:

$http({
    method: 'POST',
    url: url,
    headers: {'Content-Type': 'application/x-www-form-urlencoded'},
    data: 'username='+$scope.userName+'&password='+$scope.password
}).success(function () {});
21
moices

Voici comment cela devrait être (et s'il vous plait, aucun changement de backend ... certainement pas ... si votre pile frontale ne supporte pas application/x-www-form-urlencoded, alors jetez-la ... espérons que AngularJS le fait!

$http({
     method: 'POST',
     url: 'api_endpoint',
     headers: {'Content-Type': 'application/x-www-form-urlencoded'},
     data: 'username='+$scope.username+'&password='+$scope.password
 }).then(function(response) {
    // on success
 }, function(response) {
    // on error
 });

Fonctionne comme un charme avec AngularJS 1.5

Les gens, laissez-nous vous donner un conseil:

  • utiliser les promesses .then(success, error) lorsque vous utilisez $http, oubliez les rappels .sucess et .error (car ils sont obsolètes)

  • Depuis le site angularjs ici " Vous ne pouvez plus utiliser la chaîne JSON_CALLBACK comme espace réservé pour spécifier où la valeur du paramètre de rappel doit aller. "

Si votre modèle de données est plus complexe qu'un simple nom d'utilisateur et un mot de passe, vous pouvez toujours le faire (comme suggéré ci-dessus)

$http({
     method: 'POST',
     url: 'api_endpoint',
     headers: {'Content-Type': 'application/x-www-form-urlencoded'},
     data: json_formatted_data,
     transformRequest: function(data, headers) {
          return transform_json_to_urlcoded(data); // iterate over fields and chain key=value separated with &, using encodeURIComponent javascript function
     }
}).then(function(response) {
  // on succes
}, function(response) {
  // on error
});

Le document pour la encodeURIComponent peut être trouvé ici

3

S'il s'agit d'un formulaire, essayez de remplacer l'en-tête par:

headers[ "Content-type" ] = "application/x-www-form-urlencoded; charset=utf-8";

et si ce n'est pas un formulaire et un simple JSON, essayez cet en-tête:

headers[ "Content-type" ] = "application/json";
2
V31
$http({

    method: "POST",
    url: "/server.php",
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    data: "name='Олег'&age='28'",


}).success(function(data, status) {
    console.log(data);
    console.log(status);
});
1
user8483090

À partir de la $ http docs, cela devrait fonctionner.

  $http.post(url, data,{headers: {'Content-Type': 'application/x-www-form-urlencoded'}})
    .success(function(response) {
         // your code...
     });
1
Srinath

Bien que ma réponse soit tardive, j’ai trouvé que angular UrlSearchParams fonctionnait très bien pour moi, il s’occupe également de l’encodage des paramètres.

let params = new URLSearchParams();
params.set("abc", "def");

let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded'});
let options = new RequestOptions({ headers: headers, withCredentials: true });
this.http
.post(UrlUtil.getOptionSubmitUrl(parentSubcatId), params, options)
.catch();
1
vanval

vous devez publier un objet javascript simple, rien d'autre

           var request = $http({
                method: "post",
                url: "process.cfm",
                transformRequest: transformRequestAsFormPost,
                data: { id: 4, name: "Kim" }
            });

            request.success(
                function( data ) {
                    $scope.localData = data;
                }
            );

si vous avez php comme back-end, vous devrez faire quelques modifications supplémentaires .. checkout ce lien pour la correction du côté serveur php

1
harishr

Cela a fonctionné pour moi. J'utilise angular pour le front-end et laravel php pour le back-end. Dans mon projet, angular web envoie des données JSON à laravel back-end.

Ceci est mon contrôleur angular.

var angularJsApp= angular.module('angularJsApp',[]);
angularJsApp.controller('MainCtrl', function ($scope ,$http) {

    $scope.userName ="Victoria";
    $scope.password ="password"


       $http({
            method :'POST',
            url:'http://api.mywebsite.com.localhost/httpTest?callback=JSON_CALLBACK',
            data: { username :  $scope.userName , password: $scope.password},
            headers: {'Content-Type': 'application/json'}
        }).success(function (data, status, headers, config) {
            console.log('status',status);
            console.log('data',status);
            console.log('headers',status);
        });

});

Voici mon contrôleur php dorsal laravel.

public function httpTest(){
        if (Input::has('username')) {
            $user =Input::all();
            return  Response::json($user)->setCallback(Input::get('callback'));
        }
    }

Ceci est mon laravel routage

Route::post('httpTest','HttpTestController@httpTest');

Le résultat dans le navigateur est

statut 200
data JSON_CALLBACK ({"nom d'utilisateur": "Victoria", "mot de passe": "mot de passe", "rappel": "JSON_CALLBACK"}); httpTesting.js: 18 en-têtes fonction (c) {a || (a = sc (b)); retourne c? a [K (c)] || null: a}

Il existe une extension chrome appelée postman. Vous pouvez utiliser pour tester votre URL back-end, que cela fonctionne ou non. https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm?hl=fr

j'espère que ma réponse vous aidera.

0
meazuri