Como POSTAR dados de formulário codificados por url com $ http sem jQuery?

Eu sou novo no AngularJS e, para começar, pensei em desenvolver um novo aplicativo usando apenas o AngularJS.

Eu estou tentando fazer uma chamada AJAX para o lado do servidor, usando $http do meu aplicativo angular.

Para enviar os parâmetros, tentei o seguinte:

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

Isso está funcionando, mas está usando o jQuery em $.param . Para remover a dependência do jQuery, tentei:

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

mas isso pareceu falhar. Então eu tentei params :

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

mas isso também pareceu falhar. Então eu tentei JSON.stringify :

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

Eu encontrei essas respostas possíveis para a minha busca, mas não tive sucesso. Estou fazendo algo errado? Tenho certeza que o AngularJS forneceria essa funcionalidade, mas como?

Eu acho que você precisa fazer é transformar seus dados do object não para string JSON, mas para url params.

Do blog de Ben Nadel .

Por padrão, o serviço $ http transformará a solicitação de saída serializando os dados como JSON e, em seguida, publicando-os com o tipo de conteúdo “application / json”. Quando queremos postar o valor como uma postagem do FORM, precisamos alterar o algoritmo de serialização e postar os dados com o tipo de conteúdo, “application / x-www-form-urlencoded”.

Exemplo daqui .

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

ATUALIZAR

Para usar novos serviços adicionados com o AngularJS V1.4, consulte

  • Variáveis ​​de codificação de URL usando apenas serviços AngularJS

Variáveis ​​de codificação de URL usando apenas serviços AngularJS

Com o AngularJS 1.4 e superior, dois serviços podem manipular o processo de dados de codificação de url para solicitações POST, eliminando a necessidade de manipular os dados com transformRequest ou usando dependencies externas como jQuery:

  1. $httpParamSerializerJQLike – um serializador inspirado no .param() recomendado por jQuery ( recomendado )

  2. $httpParamSerializer – um serializador usado pelo próprio Angular para solicitações GET

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

Veja uma demonstração Plunker mais detalhada


Como são $httpParamSerializerJQLike e $httpParamSerializer diferentes?

Em geral, parece que o $httpParamSerializer usa menos formato de codificação de URL “tradicional” do que $httpParamSerializerJQLike quando se trata de estruturas de dados complexas.

Por exemplo (ignorando a codificação percentual de colchetes):

Codificando uma matriz

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

Codificando um object

 {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 

Tudo isso parece um exagero (ou não funciona) … apenas faça isso:

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

O problema é o formato de string JSON. Você pode usar uma string de URL simples nos dados:

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

Aqui está o caminho que deve ser (e por favor, sem mudanças de backend … certamente não … se sua pilha frontal não suporta application/x-www-form-urlencoded , então jogue fora … esperançosamente AngularJS faz!

 $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 um charme com o AngularJS 1.5

Gente, deixe-me dar um conselho:

  • use promises .then(success, error) ao lidar com $http , esqueça os callbacks .error e .error (como eles estão sendo preteridos)

  • Do site angularjs aqui ” Você não pode mais usar a string JSON_CALLBACK como um espaço reservado para especificar onde o valor do parâmetro de retorno de chamada deve ir.

Se o seu modelo de dados é mais complexo que apenas um nome de usuário e uma senha, você ainda pode fazer isso (como sugerido acima)

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

Documento para o encodeURIComponent pode ser encontrado aqui

Dos documentos $ http isso deve funcionar ..

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

Se for um formulário tente mudar o header para:

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

e se não for um formulário e um simples json então tente este header:

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

você precisa postar object javascript simples, nada mais

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

Se você tiver php como back-end, então você precisará fazer mais algumas modificações .. checkout este link para corrigir o lado do servidor php

Embora seja uma resposta tardia, descobri que o UrlSearchParams angular funcionava muito bem para mim, além de cuidar da codificação 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); }); 

Isso funcionou para mim. Eu uso angular para front-end e laravel php para back-end. No meu projeto, a web angular envia dados json para o backend de laravel.

Este é o meu 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 é o meu controlador de laravel de back-end php.

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

Este é o meu roteamento laravel

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

O resultado no navegador é

status 200
dados JSON_CALLBACK ({“username”: “Victoria”, “password”: “password”, “callback”: “JSON_CALLBACK”}); httpTesting.js: function de 18 headers (c) {a || (a = sc (b)); retorno c? a [K (c)] || null: a}

Existe uma extensão de cromo chamada carteiro. Você pode usar para testar seu URL de back-end, esteja ele funcionando ou não. https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm?hl=pt

espero que minha resposta ajude você.