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?
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.
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 () {});
Pour utiliser les nouveaux services ajoutés avec AngularJS V1.4, voir
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:
$httpParamSerializerJQLike
- un sérialiseur inspiré par jQuery .param()
( recommandé )
$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 */ });
_
$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
_
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) {
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 () {});
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
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";
$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);
});
À 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...
});
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();
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
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.