AngularJs $ http.post () não envia dados

Alguém poderia me dizer por que a seguinte declaração não envia os dados do post para o URL designado? A URL é chamada, mas no servidor quando imprimo $ _POST – recebo uma matriz vazia. Se eu imprimir mensagem no console antes de adicioná-lo aos dados, ele mostrará o conteúdo correto.

$http.post('request-url', { 'message' : message }); 

Eu também tentei com os dados como string (com o mesmo resultado):

 $http.post('request-url', "message=" + message); 

Parece estar funcionando quando eu uso no seguinte formato:

 $http({ method: 'POST', url: 'request-url', data: "message=" + message, headers: {'Content-Type': 'application/x-www-form-urlencoded'} }); 

mas existe uma maneira de fazer isso com o $ http.post () – e eu sempre tenho que include o header para que ele funcione? Acredito que o tipo de conteúdo acima esteja especificando o formato dos dados enviados, mas posso enviá-lo como object javascript?

Eu tive o mesmo problema usando o asp.net MVC e encontrei a solução aqui

Existe uma grande confusão entre os recém-chegados ao AngularJS quanto ao motivo pelo qual as funções abreviadas do serviço $http ( $http.post() , etc.) não parecem ser trocáveis ​​com os equivalentes jQuery ( jQuery.post() , etc.)

A diferença está em como o jQuery e o AngularJS serializam e transmitem os dados. Fundamentalmente, o problema é que o idioma do seu servidor de escolha é incapaz de entender a transmissão do AngularJS nativamente … Por padrão, o jQuery transmite dados usando

 Content-Type: x-www-form-urlencoded 

e a familiarização da serialização foo=bar&baz=moe .

O AngularJS , no entanto, transmite dados usando

 Content-Type: application/json 

e { "foo": "bar", "baz": "moe" }

Serialização JSON, que infelizmente algumas linguagens de servidor da Web – notavelmente PHP – não são desserializadas nativamente.

Funciona como um encanto.

CÓDIGO

 // Your app's root module... angular.module('MyModule', [], function($httpProvider) { // Use x-www-form-urlencoded Content-Type $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8'; /** * The workhorse; converts an object to x-www-form-urlencoded serialization. * @param {Object} obj * @return {String} */ var param = function(obj) { var query = '', name, value, fullSubName, subName, subValue, innerObj, i; for(name in obj) { value = obj[name]; if(value instanceof Array) { for(i=0; i 

Não está super claro acima, mas se você está recebendo o pedido em PHP você pode usar:

$params = json_decode(file_get_contents('php://input'),true);

Para acessar uma matriz no PHP a partir de um POST AngularJS.

Você pode definir o “Content-Type” padrão assim:

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

Sobre o formato de data :

Os methods $ http.post e $ http.put aceitam qualquer valor de object JavaScript (ou string) como parâmetro de dados. Se os dados forem um object JavaScript, serão convertidos, por padrão, em uma string JSON.

Tente usar essa variação

 function sendData($scope) { $http({ url: 'request-url', method: "POST", data: { 'message' : message } }) .then(function(response) { // success }, function(response) { // optional // failed }); } 

Eu tive um problema semelhante, e me pergunto se isso pode ser útil também: https://stackoverflow.com/a/11443066

 var xsrf = $.param({fkey: "key"}); $http({ method: 'POST', url: url, data: xsrf, headers: {'Content-Type': 'application/x-www-form-urlencoded'} }) 

Saudações,

Eu gosto de usar uma function para converter objects para postar params.

 myobject = {'one':'1','two':'2','three':'3'} Object.toparams = function ObjecttoParams(obj) { var p = []; for (var key in obj) { p.push(key + '=' + encodeURIComponent(obj[key])); } return p.join('&'); }; $http({ method: 'POST', url: url, data: Object.toparams(myobject), headers: {'Content-Type': 'application/x-www-form-urlencoded'} }) 

Isso foi finalmente resolvido em 1.4 angular usando $ httpParamSerializerJQLike

Veja https://github.com/angular/angular.js/issues/6039

 .controller('myCtrl', function($http, $httpParamSerializerJQLike) { $http({ method: 'POST', url: baseUrl, data: $httpParamSerializerJQLike({ "user":{ "email":"wahxxx@gmail.com", "password":"123456" } }), headers: 'Content-Type': 'application/x-www-form-urlencoded' })}) 

Eu uso o parametro jQuery com AngularJS post requrest. Aqui está um exemplo … crie o módulo de aplicativo AngularJS, onde myapp é definido com ng-app no seu código HTML.

 var app = angular.module('myapp', []); 

Agora vamos criar um controlador de login e um e-mail e uma senha do POST.

 app.controller('LoginController', ['$scope', '$http', function ($scope, $http) { // default post header $http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8'; // send login data $http({ method: 'POST', url: 'https://example.com/user/login', data: $.param({ email: $scope.email, password: $scope.password }), headers: {'Content-Type': 'application/x-www-form-urlencoded'} }).success(function (data, status, headers, config) { // handle success things }).error(function (data, status, headers, config) { // handle error things }); }]); 

Eu não gosto de explicar o código, é simples o suficiente para entender 🙂 Note que o param é do jQuery, então você deve instalar o jQuery e o AngularJS para fazê-lo funcionar. Aqui está uma captura de canvas.

insira a descrição da imagem aqui

Espero que isso seja útil. Obrigado!

Ao contrário do JQuery e do pedantismo, o Angular usa o formato JSON para transferência de dados POST de um cliente para o servidor (JQuery aplica x-www-form-urlencoded presumivelmente, embora JQuery e Angular usem JSON para dados imput). Portanto, há duas partes do problema: na parte do cliente js e na parte do seu servidor. Então você precisa de:

  1. colocar js parte do cliente Angular como esta:

     $http({ method: 'POST', url: 'request-url', data: {'message': 'Hello world'} }); 

E

  1. escreva na sua parte do servidor para receber dados de um cliente (se for php).

      $data = file_get_contents("php://input"); $dataJsonDecode = json_decode($data); $message = $dataJsonDecode->message; echo $message; //'Hello world' 

Nota: $ _POST não irá funcionar!

A solução funciona bem para mim, esperançosamente e para você.

Eu tive o mesmo problema com AngularJS e Node.js + Express 4 + Router

O roteador espera os dados da solicitação da postagem no corpo. Este corpo estava sempre vazio se eu seguisse o exemplo do Angular Docs

Notação 1

 $http.post('/someUrl', {msg:'hello word!'}) 

Mas se eu usei nos dados

Notação 2

 $http({ withCredentials: false, method: 'post', url: yourUrl, headers: {'Content-Type': 'application/x-www-form-urlencoded'}, data: postData }); 

Editar 1:

Caso contrário, o roteador node.js esperará os dados em req.body se usado notação 1:

 req.body.msg 

Que também envia as informações como carga útil JSON. Isso é melhor em alguns casos em que você tem arrays no seu json e x-www-form-urlencoded dará alguns problemas.

funcionou. Espero que ajude.

Para enviar dados via Post methode com $http de angularjs você precisa alterar

data: "message=" + message , com data: $.param({message:message})

Para construir a resposta do @ felipe-miosso:

  1. Faça o download como um módulo AngularJS daqui ,
  2. Instale-o
  3. Adicione ao seu aplicativo:

     var app = angular.module('my_app', [ ... , 'httpPostFix']); 

Eu não tenho a reputação de comentar, mas em resposta / adição à resposta de Don F:

$params = json_decode(file_get_contents('php://input'));

Um segundo parâmetro de true precisa ser adicionado à function json_decode para retornar corretamente um array associativo:

$params = json_decode(file_get_contents('php://input'), true);

Angular

  var payload = $.param({ jobId: 2 }); this.$http({ method: 'POST', url: 'web/api/ResourceAction/processfile', data: payload, headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }); 

WebAPI 2

 public class AcceptJobParams { public int jobId { get; set; } } public IHttpActionResult ProcessFile([FromBody]AcceptJobParams thing) { // do something with fileName parameter return Ok(); } 

Este código resolveu o problema para mim. É uma solução em nível de aplicativo:

 moduleName.config(['$httpProvider', function($httpProvider) { $httpProvider.defaults.transformRequest.push(function(data) { var requestStr; if (data) { data = JSON.parse(data); for (var key in data) { if (requestStr) { requestStr += "&" + key + "=" + data[key]; } else { requestStr = key + "=" + data[key]; } } } return requestStr; }); $httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded"; } ]); 

Adicione isto no seu arquivo js:

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

e adicione isso ao seu arquivo do servidor:

 $params = json_decode(file_get_contents('php://input'), true); 

Isso deve funcionar.

Eu também enfrentei um problema semelhante e estava fazendo algo assim e isso não funcionou. O meu controlador Spring não conseguiu ler o parâmetro de dados.

 var paramsVal={data:'"id":"1"'}; $http.post("Request URL", {params: paramsVal}); 

Mas lendo este fórum e API Doc, eu tentei seguir o caminho e isso funcionou para mim. Se alguém também tiver problemas semelhantes, você também pode tentar abaixo.

 $http({ method: 'POST', url: "Request URL", params: paramsVal, headers: {'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'} }); 

Por favor, verifique https://docs.angularjs.org/api/ng/service/ $ http # post para o que o param config faz. {data: ‘”id”: “1”‘} – Mapa de strings ou objects que serão convertidos em URL? data = “id: 1”

Esta é provavelmente uma resposta tardia, mas eu acho que a maneira mais adequada é usar o mesmo pedaço de código de uso angular ao fazer um pedido “get” usando você $httpParamSerializer terá que injetá-lo ao seu controlador para que você possa simplesmente fazer o seguinte sem ter que usar o Jquery, $http.post(url,$httpParamSerializer({param:val}))

 app.controller('ctrl',function($scope,$http,$httpParamSerializer){ $http.post(url,$httpParamSerializer({param:val,secondParam:secondVal})); } 

No meu caso, resolvo o problema assim:

 var deferred = $q.defer(); $http({ method: 'POST', url: 'myUri', data: $.param({ param1: 'blablabla', param2: JSON.stringify(objJSON) }), headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }).then( function(res) { console.log('succes !', res.data); deferred.resolve(res.data); }, function(err) { console.log('error...', err); deferred.resolve(err); } ); return deferred.promise; 

Você precisa usar JSON.stringify para cada parâmetro contendo um object JSON e, em seguida, construir seu object de dados com “$ .param” 🙂

NB: Meu “objJSON” é um object JSON contendo array, integer, string e conteúdo html. Seu tamanho total é> 3500 caracteres.

Eu sei que aceitou a resposta. Mas, seguindo, pode ajudar futuros leitores, se a resposta não lhes convier por qualquer motivo.

Angular não faz ajax mesmo que jQuery. Enquanto eu tentava seguir o guia para modificar o $httpprovider angular, encontrei outros problemas. Por exemplo, eu uso o codeigniter em que a function $this->input->is_ajax_request() sempre falha (que foi escrita por outro programador e usada globalmente, portanto não posso mudar) dizendo que esta não era uma requisição ajax real.

Para resolvê-lo, aceitei a promise adiada . Eu testei no Firefox e IE9 e funcionou.

Eu tenho a seguinte function definida fora de qualquer código angular. Essa function faz uma chamada regular de jquery ajax e retorna um object de adiamento / promise (ainda estou aprendendo).

 function getjQueryAjax(url, obj){ return $.ajax({ type: 'post', url: url, cache: true, data: obj }); } 

Então eu estou chamando de código angular usando o seguinte código. Por favor, note que temos que atualizar o $scope manualmente usando $scope.$apply() .

  var data = { media: "video", scope: "movies" }; var rPromise = getjQueryAjax("myController/getMeTypes" , data); rPromise.success(function(response){ console.log(response); $scope.$apply(function(){ $scope.testData = JSON.parse(response); console.log($scope.testData); }); }).error(function(){ console.log("AJAX failed!"); }); 

Esta pode não ser a resposta perfeita, mas permitiu-me usar chamadas jquery ajax com angular e permitiu-me atualizar o $scope .

Eu tive o mesmo problema em expressar .. para resolver você tem que usar bodyparser para analisar objects json antes de enviar solicitações http ..

 app.use(bodyParser.json()); 

Estou usando webservices asp.net WCF com js angular e abaixo do código trabalhado:

  $http({ contentType: "application/json; charset=utf-8",//required method: "POST", url: '../../operation/Service.svc/user_forget', dataType: "json",//optional data:{ "uid_or_phone": $scope.forgettel, "user_email": $scope.forgetemail }, async: "isAsync"//optional }).success( function (response) { $scope.userforgeterror = response.d; }) 

Espero que ajude.

Não encontrou um trecho de código completo de como usar o método $ http.post para enviar dados para o servidor e por que ele não estava funcionando nesse caso.

Explicações do trecho de código abaixo …

  1. Eu estou usando a function jQuery $ .param para serializar os dados JSON para www post data
  2. Configurando o Content-Type na variável de configuração que será passada junto com a requisição do angularJS $ http.post que instrui o servidor para o qual estamos enviando dados no formato www post.

  3. Observe o método $ htttp.post, no qual estou enviando o primeiro parâmetro como url, o segundo parâmetro como dados (serializado) e o terceiro parâmetro como config.

Código restante é auto-compreendido.

 $scope.SendData = function () { // use $.param jQuery function to serialize data from JSON var data = $.param({ fName: $scope.firstName, lName: $scope.lastName }); var config = { headers : { 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;' } } $http.post('/ServerRequest/PostDataResponse', data, config) .success(function (data, status, headers, config) { $scope.PostDataResponse = data; }) .error(function (data, status, header, config) { $scope.ResponseDetails = "Data: " + data + "
status: " + status + "
headers: " + header + "
config: " + config; }); };

Veja o exemplo de código do método $ http.post aqui .

Se estiver usando Angular> = 1.4 , aqui está a solução mais limpa usando o serializador fornecido pela Angular :

 angular.module('yourModule') .config(function ($httpProvider, $httpParamSerializerJQLikeProvider){ $httpProvider.defaults.transformRequest.unshift($httpParamSerializerJQLikeProvider.$get()); $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8'; }); 

E então você pode simplesmente fazer isso em qualquer lugar no seu aplicativo:

 $http({ method: 'POST', url: '/requesturl', data: { param1: 'value1', param2: 'value2' } }); 

E serializará corretamente os dados como param1=value1&param2=value2 e os enviará para /requesturl com o application/x-www-form-urlencoded; charset=utf-8 application/x-www-form-urlencoded; charset=utf-8 Cabeçalho Content-Type como normalmente é esperado com solicitações POST nos terminais.

TL; DR

Durante minha pesquisa, descobri que a resposta para esse problema vem em muitos sabores diferentes; alguns são muito complicados e dependem de funções personalizadas, alguns dependem do jQuery e alguns são incompletos ao sugerir que você só precisa definir o header.

Se você acabou de definir o header Content-Type , o ponto final verá os dados POST, mas não estará no formato padrão porque, a menos que você forneça uma string como seus data ou serialize manualmente o object de dados, todos serão serializado como JSON por padrão e pode ser interpretado incorretamente no nó de extremidade.

por exemplo, se o serializador correto não foi definido no exemplo acima, ele seria visto no terminal como:

 {"param1":"value1","param2":"value2"} 

E isso pode levar a uma análise inesperada, por exemplo, o ASP.NET trata-o como um nome de parâmetro null , com {"param1":"value1","param2":"value2"} como valor; ou o Fiddler interpreta de outra forma, com {"param1":"value1","param2":"value2"} como o nome do parâmetro e null como o valor.

Semelhante ao formato de trabalho sugerido pelo OP e à resposta de Denison, exceto pelo uso de $http.post vez de apenas $http e que ainda depende do jQuery.

O bom de usar o jQuery aqui é que objects complexos são passados ​​corretamente; contra a conversão manual em parâmetros de URL que podem distorcer os dados.

 $http.post( 'request-url', jQuery.param( { 'message': message } ), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }); 

Quando eu tive esse problema, o parâmetro que eu estava postando acabou sendo uma matriz de objects em vez de um object simples.

Apenas atualizado do ângulo 1.2 para 1.3, encontrou um problema no código. Transformar um recurso levará a um loop infinito porque (eu acho) da promise $ retendo novamente o mesmo object. Talvez ajude alguém …

Eu poderia consertar isso por:

 [...] /** * The workhorse; converts an object to x-www-form-urlencoded serialization. * @param {Object} obj * @return {String} */ var param = function (obj) { var query = '', name, value, fullSubName, subName, subValue, innerObj, i; angular.forEach(obj, function(value, name) { + if(name.indexOf("$promise") != -1) { + return; + } value = obj[name]; if (value instanceof Array) { for (i = 0; i < value.length; ++i) { [...] 

Eu tenho usado o código da resposta aceita (código de Felipe) por um tempo e tem funcionado muito bem (obrigado, Felipe!).

No entanto, recentemente descobri que há problemas com objects vazios ou matrizes. Por exemplo, ao enviar este object:

 { A: 1, B: { a: [ ], }, C: [ ], D: "2" } 

O PHP não parece ver B e C. Obtém isso:

 [ "A" => "1", "B" => "2" ] 

Uma olhada na solicitação real no Chrome mostra isso:

 A: 1 : D: 2 

Eu escrevi um trecho de código alternativo. Parece funcionar bem com meus casos de uso, mas não testei extensivamente, portanto, use com caucanvas.

Eu usei o TypeScript porque gosto de digitar forte, mas seria fácil convertê-lo em JS puro:

 angular.module("MyModule").config([ "$httpProvider", function($httpProvider: ng.IHttpProvider) { // Use x-www-form-urlencoded Content-Type $httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded;charset=utf-8"; function phpize(obj: Object | any[], depth: number = 1): string[] { var arr: string[] = [ ]; angular.forEach(obj, (value: any, key: string) => { if (angular.isObject(value) || angular.isArray(value)) { var arrInner: string[] = phpize(value, depth + 1); var tmpKey: string; var encodedKey = encodeURIComponent(key); if (depth == 1) tmpKey = encodedKey; else tmpKey = `[${encodedKey}]`; if (arrInner.length == 0) { arr.push(`${tmpKey}=`); } else { arr = arr.concat(arrInner.map(inner => `${tmpKey}${inner}`)); } } else { var encodedKey = encodeURIComponent(key); var encodedValue; if (angular.isUndefined(value) || value === null) encodedValue = ""; else encodedValue = encodeURIComponent(value); if (depth == 1) { arr.push(`${encodedKey}=${encodedValue}`); } else { arr.push(`[${encodedKey}]=${encodedValue}`); } } }); return arr; } // Override $http service's default transformRequest ($httpProvider.defaults).transformRequest = [ function(data: any) { if (!angular.isObject(data) || data.toString() == "[object File]") return data; return phpize(data).join("&"); } ]; } ]); 

É menos eficiente que o código de Felipe, mas não acho que seja importante, já que deve ser imediato, comparado à sobrecarga geral da própria solicitação HTTP.

Agora o PHP mostra:

 [ "A" => "1", "B" => [ "a" => "" ], "C" => "", "D" => "2" ] 

Até onde sei, não é possível fazer com que o PHP reconheça que Ba e C são matrizes vazias, mas pelo menos as teclas aparecem, o que é importante quando existe um código que depende de uma certa estrutura mesmo quando ela está essencialmente vazia.

Observe também que ele converte s indefinidos e null s em cadeias vazias.

Se você está usando PHP, esta é uma maneira fácil de acessar um array em PHP a partir de um POST AngularJS.

 $params = json_decode(file_get_contents('php://input'),true); 

Eu resolvi isso pelos códigos abaixo:

Lado do Cliente (Js):

  $http({ url: me.serverPath, method: 'POST', data: data, headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, }). success(function (serverData) { console.log("ServerData:", serverData); ...... 

observe que os dados são um object.

No servidor (ASP.NET MVC):

 [AllowCrossSiteJson] public string Api() { var data = JsonConvert.DeserializeObject(Request.Form[0]); if (data == null) return "Null Request"; var bl = Page.Bl = new Core(this); return data.methodName; } 

e ‘AllowCrossSiteJsonAttribute’ é necessário para solicitações entre domínios:

 public class AllowCrossSiteJsonAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*"); base.OnActionExecuting(filterContext); } } 

Espero que isso tenha sido útil.

Não é culpa do angular. Angular é projetado para funcionar no mundo JSON. Portanto, quando o serviço $ http envia uma solicitação AJAX, ele envia todos os seus dados como uma carga útil, não como dados de formulário, para que o aplicativo de back-end possa manipulá-los. Mas o jQuery faz algumas coisas internamente. Você instrui o módulo $ ajax do jQuery para ligar os dados de formulário como JSON, mas antes de enviar o pedido AJAX, ele serializa o JSON e adiciona o header application/x-www-form-urlencoded . Dessa forma, seu aplicativo de backend pode receber dados de formulário em forma de parâmetros de postagem e não de JSON.

Mas você pode modificar o comportamento padrão do serviço $ http angular

  1. Adicionando header
  2. Json de serialização

$ httpParamSerializerJQLike é o serviço embutido do angular que serializa o json da mesma forma que o $ .param faz do jQuery.

 $http({ method: 'POST', url: 'request-url', data: $httpParamSerializerJQLike(json-form-data), headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8;' } }); 

Se você precisa de um plugin para serializar dados de formulário em JSON primeiro, use este https://github.com/marioizquierdo/jquery.serializeJSON

Intereting Posts