AngularJs $ http.post () non invia dati

Qualcuno potrebbe dirmi perché la seguente dichiarazione non invia i dati dei post all’URL designato? L’url viene chiamato ma sul server quando stampo $ _POST – Ottengo un array vuoto. Se stampo un messaggio nella console prima di aggiungerlo ai dati, mostra il contenuto corretto.

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

Ho anche provato con i dati come stringa (con lo stesso risultato):

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

Sembra che funzioni quando lo uso nel seguente formato:

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

ma c’è un modo per farlo con $ http.post () – e devo sempre includere l’intestazione affinché funzioni? Credo che il tipo di contenuto di cui sopra sta specificando il formato dei dati inviati, ma posso inviarlo come object javascript?

Ho avuto lo stesso problema con asp.net MVC e ho trovato la soluzione qui

C’è molta confusione tra i nuovi arrivati ​​in AngularJS sul motivo per cui le funzioni di stenografia del servizio $http ( $http.post() , ecc.) Non sembrano essere scambiabili con gli equivalenti jQuery ( jQuery.post() , ecc.)

La differenza sta nel modo in cui jQuery e AngularJS serializzano e trasmettono i dati. Fondamentalmente, il problema sta nel fatto che il linguaggio del server scelto non è in grado di comprendere la trasmissione di AngularJS in modo nativo … Per impostazione predefinita, jQuery trasmette i dati usando

 Content-Type: x-www-form-urlencoded 

e la familiare foo=bar&baz=moe serialization.

AngularJS , tuttavia, trasmette i dati utilizzando

 Content-Type: application/json 

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

Serializzazione JSON, che sfortunatamente alcuni linguaggi di Web server, in particolare PHP, non sono non serializzati in modo nativo.

Funziona come un fascino.

CODICE

 // 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 

Non è molto chiaro sopra, ma se stai ricevendo la richiesta in PHP puoi usare:

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

Per accedere a un array in PHP da un POST di AngularJS.

Puoi impostare il “Content-Type” predefinito in questo modo:

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

Informazioni sul formato dei data :

I metodi $ http.post e $ http.put accettano qualsiasi valore di object JavaScript (o stringa) come parametro dei dati. Se i dati sono oggetti JavaScript, per impostazione predefinita verranno convertiti in una stringa JSON.

Prova ad usare questa variazione

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

Ho avuto un problema simile, e mi chiedo se questo può essere utile pure: 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'} }) 

Saluti,

Mi piace usare una funzione per convertire oggetti in post-parametri.

 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'} }) 

Questo è stato finalmente risolto nell’angular 1.4 usando $ httpParamSerializerJQLike

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

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

Io uso jQuery param con AngularJS post requrest. Ecco un esempio … crea il modulo di applicazione AngularJS, dove myapp è definito con ng-app nel tuo codice HTML.

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

Ora creiamo un controller di accesso e l’e-mail e la password 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 }); }]); 

Non mi piace analizzare il codice, è abbastanza semplice da capire 🙂 Nota che param è di jQuery, quindi devi installare sia jQuery che AngularJS per farlo funzionare. Ecco uno screenshot.

inserisci la descrizione dell'immagine qui

Spero che questo sia utile. Grazie!

A differenza di JQuery e per motivi di pedanteria, Angular utilizza il formato JSON per il trasferimento di dati POST da un client al server (JQuery applica x-www-form-urlencoded presumibilmente, sebbene JQuery e Angular utilizzino JSON per l’imput di dati). Quindi ci sono due parti del problema: nella parte client js e nella parte server. Quindi hai bisogno di:

  1. metti la parte client js Angular in questo modo:

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

E

  1. scrivi nella tua parte server per ricevere dati da un client (se è php).

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

Nota: $ _POST non funzionerà!

La soluzione funziona per me bene, spero e per te.

Ho avuto lo stesso problema con AngularJS e Node.js + Express 4 + Router

Il router si aspetta i dati dalla richiesta del post nel corpo. Questo corpo era sempre vuoto se seguivo l’esempio di Angular Docs

Notazione 1

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

Ma se l’ho usato nei dati

Notazione 2

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

Modifica 1:

Altrimenti il ​​router node.js aspetterà i dati in req.body se usato notazione 1:

 req.body.msg 

Che invia anche le informazioni come payload JSON. Questo è meglio in alcuni casi in cui si hanno array in json e x-www-form-urlencoded darà alcuni problemi.

ha funzionato. Spero che sia d’aiuto.

Per inviare dati tramite il metodo Post con $http di angularjs è necessario modificare

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

Per build la risposta di @ felipe-miosso:

  1. Scaricalo come modulo AngularJS da qui ,
  2. Installalo
  3. Aggiungilo alla tua domanda:

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

Non ho la reputazione di commentare, ma in risposta / aggiunta alla risposta di Don F:

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

Un secondo parametro di true deve essere aggiunto alla funzione json_decode per restituire correttamente un array associativo:

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

Angolare

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

Questo codice ha risolto il problema per me. È una soluzione a livello di applicazione:

 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"; } ]); 

Aggiungi questo nel tuo file js:

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

e aggiungi questo al tuo file server:

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

Questo dovrebbe funzionare

Ho anche affrontato un problema simile e stavo facendo qualcosa di simile e questo non ha funzionato. Il mio controller Spring non era in grado di leggere i parametri dei dati.

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

Ma leggendo questo forum e l’API Doc, ho provato a seguire la strada e questo ha funzionato per me. Se qualcuno ha anche un problema simile, puoi provare anche in basso.

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

Si prega di controllare https://docs.angularjs.org/api/ng/service/ $ http # post per ciò che param config fa. {data: ‘”id”: “1”‘} – Mappa di stringhe o oggetti che verranno convertiti in URL? data = “id: 1”

questa è probabilmente una risposta tardiva, ma penso che il modo più corretto sia usare lo stesso pezzo di codice angular quando si fa una richiesta “get” usando $httpParamSerializer iniettarlo sul controller in modo da poter semplicemente fare quanto segue senza dovendo usare Jquery, $http.post(url,$httpParamSerializer({param:val}))

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

Nel mio caso risolvo il problema in questo modo:

 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; 

Devi usare JSON.stringify per ogni parametro che contiene un object JSON, quindi creare il tuo object dati con “$ .param” 🙂

NB: Il mio “objJSON” è un object JSON contenente un array, un intero, una stringa e un contenuto html. La sua dimensione totale è> 3500 caratteri.

So che ha accettato la risposta. Ma, seguendo potrebbe aiutare ai futuri lettori, se la risposta non li soddisfa per qualsiasi motivo.

Angular non fa ajax come jQuery. Mentre $httpprovider a seguire la guida per modificare l’angular $httpprovider , ho riscontrato altri problemi. Ad esempio, io uso il codeigniter in cui la funzione $this->input->is_ajax_request() sempre fallita (che è stata scritta da un altro programmatore e usata globalmente, quindi non posso cambiare) dicendo che questa non era una richiesta reale.

Per risolverlo, ho preso l’aiuto della promise differita . L’ho provato su Firefox, ie ie9 e ha funzionato.

Ho la seguente funzione definita al di fuori di qualsiasi codice angular. Questa funzione rende normale la chiamata ajax jquery e restituisce object differito / promesso (sto ancora imparando).

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

Allora lo chiamo codice angular usando il seguente codice. Si noti che è necessario aggiornare $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!"); }); 

Questa potrebbe non essere la risposta perfetta, ma mi ha permesso di usare jquery ajax con le chiamate angolari e mi ha permesso di aggiornare il $scope .

Ho avuto lo stesso problema in express .. per risolvere devi usare bodyparser per analizzare oggetti json prima di inviare richieste http …

 app.use(bodyParser.json()); 

Sto usando i webservices di asp.net WCF con js angolari e sotto il codice lavorato:

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

Spero che sia d’aiuto.

Non ho trovato uno snippet di codice completo su come utilizzare il metodo $ http.post per inviare dati al server e perché non funzionava in questo caso.

Spiegazioni del seguente snippet di codice …

  1. Sto usando la funzione jQuery $ .param per serializzare i dati JSON su www post data
  2. Impostazione del tipo di contenuto nella variabile di configurazione che verrà passata insieme alla richiesta di angularJS $ http.post che indica al server che stiamo inviando dati nel formato di posta elettronica www.

  3. Si noti il ​​metodo $ htttp.post, dove sto inviando 1 ° parametro come url, 2 ° parametro come dati (serializzato) e 3 ° parametro come config.

Il codice rimanente è capito da sé.

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

Guarda l’esempio di codice del metodo $ http.post qui .

Se si utilizza Angolare> = 1.4 , ecco la soluzione più pulita utilizzando il serializzatore fornito da 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 poi puoi semplicemente farlo ovunque nella tua app:

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

E serializzerà correttamente i dati come param1=value1&param2=value2 e lo invierà a /requesturl con l’ application/x-www-form-urlencoded; charset=utf-8 application/x-www-form-urlencoded; charset=utf-8 Intestazione Content-Type come normalmente prevista con le richieste POST sugli endpoint.

TL; DR

Durante la mia ricerca ho scoperto che la risposta a questo problema arriva in molti gusti diversi; alcuni sono molto contorti e dipendono da funzioni personalizzate, alcuni dipendono da jQuery e alcuni sono incompleti nel suggerire che è sufficiente impostare l’intestazione.

Se si imposta l’intestazione Content-Type , il punto finale vedrà i dati POST, ma non sarà nel formato standard perché, a meno che non si fornisca una stringa come data o si serializzi manualmente l’object dati, sarà tutto serializzato come JSON per impostazione predefinita e potrebbe essere interpretato erroneamente sull’endpoint.

ad esempio se il serializzatore corretto non è stato impostato nell’esempio precedente, verrebbe visualizzato nell’endpoint come:

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

E ciò può portare a un’analisi inaspettata, ad esempio ASP.NET lo considera come un nome di parametro null , con {"param1":"value1","param2":"value2"} come valore; o Fiddler lo interpreta in un altro modo, con {"param1":"value1","param2":"value2"} come nome parametro e null come valore.

Simile al formato di lavoro suggerito dall’OP e alla risposta di Denison, tranne che usando $http.post invece di solo $http e dipende ancora da jQuery.

La cosa buona dell’utilizzo di jQuery qui è che gli oggetti complessi vengono passati correttamente; contro la conversione manuale in parametri URL che potrebbero alterare i dati.

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

Quando ho avuto questo problema il parametro che stavo pubblicando si è rivelato essere una matrice di oggetti invece di un object semplice.

Appena aggiornato da 1,2 a 1,3 angolari, ho riscontrato un problema nel codice. Trasformare una risorsa porterà ad un ciclo infinito perché (penso) della $ promise che mantiene lo stesso object. Forse aiuterà qualcuno …

Potrei risolvere il problema con:

 [...] /** * 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) { [...] 

Sto usando il codice della risposta accettata (il codice di Felipe) per un po ‘e sta funzionando alla grande (grazie, Felipe!).

Tuttavia, recentemente ho scoperto che ha problemi con oggetti o array vuoti. Ad esempio, quando si invia questo object:

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

PHP non sembra vedere B e C affatto. Ottiene questo:

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

Uno sguardo alla richiesta effettiva in Chrome mostra questo:

 A: 1 : D: 2 

Ho scritto uno snippet di codice alternativo. Sembra funzionare bene con i miei casi d’uso ma non l’ho testato estensivamente, quindi usalo con caucanvas.

Ho usato TypeScript perché mi piace scrivere forte, ma sarebbe facile convertire in pure JS:

 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("&"); } ]; } ]); 

È meno efficiente del codice di Felipe, ma non penso che importi molto visto che dovrebbe essere immediato rispetto al sovraccarico complessivo della richiesta HTTP stessa.

Ora PHP mostra:

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

Per quanto ne so non è ansible ottenere che PHP riconosca che Ba e C sono array vuoti, ma almeno i tasti appaiono, il che è importante quando c’è un codice che si basa su una certa struttura anche quando è essenzialmente vuoto all’interno.

Si noti inoltre che converte s indefiniti e null s in stringhe vuote.

Se usi PHP questo è un modo semplice per accedere a un array in PHP da un POST di AngularJS.

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

Ho risolto questo con i seguenti codici:

Lato client (Js):

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

notare che i dati sono un object.

Sul server (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’ è necessario per le richieste tra domini:

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

Spero che questo sia stato utile.

Non è colpa dell’angular. Angular è progettato per funzionare nel mondo JSON. Pertanto, quando il servizio $ http invia una richiesta AJAX, invia tutti i dati come payload, non come dati di forma, in modo che l’applicazione back-end possa gestirli. Ma jQuery fa alcune cose internamente. Istruisci il modulo $ ajax di jQuery per bind i dati del modulo come JSON, ma prima di inviare la richiesta AJAX, serializza JSON e aggiungi l’intestazione application/x-www-form-urlencoded . In questo modo l’applicazione back-end è in grado di ricevere i dati del modulo sotto forma di parametri di post e non JSON.

Ma è ansible modificare il comportamento predefinito del servizio $ http angular di

  1. Aggiungere intestazione
  2. Serializzazione JSON

$ httpParamSerializerJQLike è il servizio integrato di angular che serializza json nello stesso modo $ .param fa di jQuery.

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

Se hai bisogno di un plug-in per serializzare i dati del modulo in JSON, usa questo https://github.com/marioizquierdo/jquery.serializeJSON