¿Cómo PUESTO datos de formulario urlencoded con $ http sin jQuery?

Soy nuevo en AngularJS, y para empezar, pensé en desarrollar una nueva aplicación usando solo AngularJS.

Estoy tratando de hacer una llamada AJAX al lado del servidor, usando $http desde mi aplicación Angular.

Para enviar los parámetros, intenté lo siguiente:

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

Esto está funcionando, pero también está usando jQuery en $.param . Para eliminar la dependencia de jQuery, probé:

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

pero esto pareció fallar. Entonces probé params :

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

pero esto también pareció fallar. Entonces probé JSON.stringify :

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

Encontré estas posibles respuestas a mi búsqueda, pero no tuve éxito. ¿Estoy haciendo algo mal? Estoy seguro de que AngularJS proporcionaría esta funcionalidad, pero ¿cómo?

Creo que lo que debes hacer es transformar tus datos de un objeto a una cadena JSON, pero a url params.

Del blog de Ben Nadel .

Por defecto, el servicio $ http transformará la solicitud saliente serializando los datos como JSON y luego publicándolos con el tipo de contenido “application / json”. Cuando queremos publicar el valor como una publicación FORM, tenemos que cambiar el algoritmo de serialización y publicar los datos con el tipo de contenido, “application / x-www-form-urlencoded”.

Ejemplo de aquí .

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

ACTUALIZAR

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

  • Variables de encoding URL que utilizan solo servicios AngularJS

Variables de encoding URL que utilizan solo servicios AngularJS

Con AngularJS 1.4 y superior, dos servicios pueden manejar el proceso de encoding de URL de datos para solicitudes POST, eliminando la necesidad de manipular los datos con transformRequest o usando dependencias externas como jQuery:

  1. $httpParamSerializerJQLike – un serializador inspirado en jQuery’s .param() ( recomendado )

  2. $httpParamSerializer : un serializador utilizado por Angular para solicitudes GET

Ejemplo de uso

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

Vea una demostración más detallada de Plunker


¿En qué se $httpParamSerializerJQLike y $httpParamSerializer

En general, parece que $httpParamSerializer utiliza un formato de encoding de url menos “tradicional” que $httpParamSerializerJQLike cuando se trata de estructuras de datos complejas.

Por ejemplo (ignorando el porcentaje de encoding de corchetes):

Codificando una matriz

 {sites:['google', 'Facebook']} // Object with array property sites[]=google&sites[]=facebook // Result with $httpParamSerializerJQLike sites=google&sites=facebook // Result with $httpParamSerializer 

Codificando un objeto

 {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 

Todos estos parecen excesivos (o no funcionan) … simplemente haz esto:

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

El problema es el formato de cadena JSON. Puede usar una cadena de URL simple en los datos:

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

Así es como debe ser (y por favor, no hay cambios en el servidor … ciertamente no … si su stack frontal no es compatible con application/x-www-form-urlencoded , entonces tírelo … ¡con suerte AngularJS lo hace!

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

Funciona como un encanto con AngularJS 1.5

Gente, déjenos dar algunos consejos:

  • use promesas .then(success, error) cuando se trata de $http , olvídese de las devoluciones de llamada .sucess y .error (ya que están en desuso)

  • Desde el sitio angularjs aquí ” Ya no puede usar la cadena JSON_CALLBACK como marcador de posición para especificar a dónde debe ir el valor del parámetro de callback.

Si su modelo de datos es más complejo que solo un nombre de usuario y una contraseña, aún puede hacer eso (como se sugirió anteriormente)

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

El documento para el encodeURIComponent se puede encontrar aquí

Desde $ http docs esto debería funcionar …

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

Si es un formulario, intente cambiar el encabezado a:

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

y si no es una forma y un json simple, intente con este encabezado:

 headers[ "Content-type" ] = "application/json"; 

necesitas publicar un objeto JavaScript simple, nada más

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

si tienes php como back-end, entonces necesitarás hacer algunas modificaciones más. revisa este enlace para arreglar el lado del servidor php

Aunque fue una respuesta tardía, encontré que el angular UrlSearchParams funcionó muy bien para mí, también se encarga de la encoding de parámetros.

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

Esto funcionó para mí. Uso angular para front-end y laravel php para back-end. En mi proyecto, la web angular envía datos json al back-end de laravel.

Este es mi controlador 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); }); }); 

Este es mi controlador de latencia de back-end php.

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

Este es mi enrutamiento laravel

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

El resultado en el navegador es

estado 200
datos JSON_CALLBACK ({“nombre de usuario”: “Victoria”, “contraseña”: “contraseña”, “callback”: “JSON_CALLBACK”}); httpTesting.js: función de encabezados 18 (c) {a || (a = sc (b)); return c? a [K (c)] || null: a}

Hay una extensión de Chrome llamada cartero. Puede usar para probar su url de back-end, ya sea que esté funcionando o no. https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm?hl=es

con suerte, mi respuesta te ayudará.