it-swarm.com.de

AngularJs $ http.post () sendet keine Daten

Kann mir jemand sagen, warum die folgende Anweisung die Post-Daten nicht an die angegebene URL sendet? Die URL wird aufgerufen, aber auf dem Server, wenn ich $ _POST drucke - bekomme ich ein leeres Array. Wenn ich eine Nachricht in der Konsole drucke, bevor ich sie zu den Daten hinzufüge, wird der richtige Inhalt angezeigt.

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

Ich habe es auch mit den Daten als String versucht (mit dem gleichen Ergebnis):

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

Es scheint zu funktionieren, wenn ich es in folgendem Format verwende:

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

aber gibt es eine Möglichkeit, dies mit $ http.post () zu tun - und muss ich immer den Header einfügen, damit es funktioniert? Ich glaube, dass der obige Inhaltstyp das Format der gesendeten Daten angibt, aber kann ich sie als Javascript-Objekt senden?

331
Spencer Mark

Ich hatte das gleiche Problem mit asp.net MVC und fand die Lösung hier

Neulinge von AngularJS sind sehr verwirrt darüber, warum die $http -Dienst-Kurzschriftfunktionen ($http.post() usw.) nicht funktionieren. ' Es scheint nicht mit den jQuery Äquivalenten (jQuery.post(), etc.) austauschbar zu sein.

Der Unterschied besteht darin, wie jQuery und AngularJS die Daten serialisieren und übertragen. Grundsätzlich liegt das Problem darin, dass die von Ihnen gewählte Serversprache die AngularJS-Übertragung von Haus aus nicht versteht ... Standardmäßig überträgt jQuery Daten mithilfe von

Content-Type: x-www-form-urlencoded

und die vertraute foo=bar&baz=moe Serialisierung.

AngularJS überträgt jedoch Daten mit

Content-Type: application/json 

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

JSON-Serialisierung, die leider einige Webserver-Sprachen - insbesondere PHP - nicht nativ deserialisieren.

Klappt wunderbar.

CODE

// 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<value.length; ++i) {
          subValue = value[i];
          fullSubName = name + '[' + i + ']';
          innerObj = {};
          innerObj[fullSubName] = subValue;
          query += param(innerObj) + '&';
        }
      }
      else if(value instanceof Object) {
        for(subName in value) {
          subValue = value[subName];
          fullSubName = name + '[' + subName + ']';
          innerObj = {};
          innerObj[fullSubName] = subValue;
          query += param(innerObj) + '&';
        }
      }
      else if(value !== undefined && value !== null)
        query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&';
    }

    return query.length ? query.substr(0, query.length - 1) : query;
  };

  // Override $http service's default transformRequest
  $httpProvider.defaults.transformRequest = [function(data) {
    return angular.isObject(data) && String(data) !== '[object File]' ? param(data) : data;
  }];
});
341
Felipe Miosso

Es ist oben nicht ganz klar, aber wenn Sie die Anfrage in PHP erhalten, können Sie Folgendes verwenden:

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

So greifen Sie über einen AngularJS-POST auf ein Array in PHP zu.

114
Don F

Sie können den Standard-Inhaltstyp wie folgt festlegen:

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

Über das data Format:

Die Methoden $ http.post und $ http.put akzeptieren einen beliebigen JavaScript-Objektwert (oder eine Zeichenfolge) als Datenparameter. Wenn es sich bei Daten um ein JavaScript-Objekt handelt, werden diese standardmäßig in eine JSON-Zeichenfolge konvertiert.

Versuchen Sie, diese Variante zu verwenden

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

Ich hatte ein ähnliches Problem und frage mich, ob dies auch nützlich sein kann: 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'}
})

Grüße,

56
ericson.cepeda

Ich verwende gerne eine Funktion, um Objekte in Post-Parameter umzuwandeln.

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'}
})
32
Rômulo Collopy

Dies wurde schließlich in angular 1.4 mit $ httpParamSerializerJQLike behoben.

Siehe 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'
})})
30
Stetzon

Ich benutze jQuery param mit AngularJS post requrest. Hier ist ein Beispiel ... ein AngularJS-Anwendungsmodul erstellen, in dem myapp mit ng-app in Ihrem HTML-Code definiert ist.

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

Nun erstellen wir einen Login-Controller und POST E-Mail und Passwort.

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

Ich erkläre den Code nicht gern, er ist einfach zu verstehen :) Beachten Sie, dass param von jQuery stammt. Sie müssen daher sowohl jQuery als auch AngularJS installieren, damit er funktioniert. Hier ist ein Screenshot.

enter image description here

Hoffe das ist hilfreich. Vielen Dank!

17
Madan Sapkota

Ich hatte das gleiche Problem mit AngularJS und Node.js + Express 4 + Router

Der Router erwartet die Daten von der Post-Anfrage im Body. Dieser Körper war immer leer, wenn ich dem Beispiel von Angular Docs folgte

Notation 1

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

Aber wenn ich es in den Daten verwendet habe

Notation 2

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

Bearbeiten 1:

Andernfalls erwartet der Router von node.js die Daten in der angeforderten Anzahl, wenn die Notation 1 verwendet wird:

req.body.msg

Welches sendet auch die Informationen als JSON-Payload. Dies ist in einigen Fällen besser, in denen Sie Arrays in Ihrem json- und x-www-form-urlencoded-Code haben, was zu Problemen führen kann.

es funktionierte. Ich hoffe es hilft.

10
alknows

Im Gegensatz zu JQuery verwendet Angular aus Gründen der Pedanterie das JSON-Format für die POST -Datenübertragung von einem Client auf den Server (JQuery wendet vermutlich x-www-form-urlencoded an, obwohl JQuery und Angular JSON für die Dateneingabe verwenden). Daher gibt es zwei Teile des Problems: im js-Client-Teil und in Ihrem Server-Teil. Also brauchst du:

  1. setze js Angular client part so:

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

UND

  1. schreiben Sie in Ihren Server-Teil, um Daten von einem Client zu erhalten (wenn es PHP ist).

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

Hinweis: $ _POST funktioniert nicht!

Die Lösung funktioniert hoffentlich gut für mich und für Sie.

9
Roman

Um Daten über die Postmethode mit $http von anglejs zu senden, müssen Sie ändern

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

Aufbauend auf der Antwort von @ felipe-miosso:

  1. Laden Sie es als AngularJS-Modul von hier herunter ,
  2. Es installieren
  3. Fügen Sie es Ihrer Anwendung hinzu:

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

Ich habe nicht den Ruf, Kommentare abzugeben, aber als Antwort/Ergänzung zu Don Fs Antwort:

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

Ein zweiter Parameter von true muss der Funktion json_decode hinzugefügt werden, um ein assoziatives Array ordnungsgemäß zurückzugeben:

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

6
Esten

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

Dieser Code hat das Problem für mich gelöst. Es ist eine Lösung auf Anwendungsebene:

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

Fügen Sie dies in Ihre js-Datei ein:

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

und füge dies zu deiner Server-Datei hinzu:

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

Das sollte funktionieren.

5

dies ist wahrscheinlich eine späte Antwort, aber ich denke, der beste Weg ist, das gleiche Stück Code angular zu verwenden, wenn Sie eine "get" -Anforderung unter Verwendung von you $httpParamSerializer ausführen Sie können einfach Folgendes tun, ohne Jquery zu verwenden, $http.post(url,$httpParamSerializer({param:val}))

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

In meinem Fall löse ich das Problem folgendermaßen:

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;

Sie müssen JSON.stringify für jeden Parameter verwenden, der ein JSON-Objekt enthält, und dann Ihr Datenobjekt mit "$ .param" erstellen :-)

NB: Mein "objJSON" ist ein JSON-Objekt, das Array-, Integer-, String- und HTML-Inhalt enthält. Seine Gesamtgröße beträgt> 3500 Zeichen.

4
bArraxas

Ich hatte auch ein ähnliches Problem und ich habe so etwas gemacht und das hat nicht funktioniert. Mein Spring-Controller konnte die Datenparameter nicht lesen.

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

Aber als ich dieses Forum und API Doc las, versuchte ich es auf folgende Weise und das funktionierte für mich. Wenn jemand auch ein ähnliches Problem hat, können Sie es auch auf folgende Weise versuchen.

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

Bitte überprüfen Sie https://docs.angularjs.org/api/ng/service/ $ http # post, was param config bewirkt. {data: '"id": "1"'} - Zuordnung von Zeichenfolgen oder Objekten, die in URL umgewandelt werden? data = "id: 1"

4
Viraj

Ich weiß, hat geantwortet. Aber das Folgen könnte zukünftigen Lesern helfen, wenn die Antwort aus irgendeinem Grund nicht zu ihnen passt.

Angular hat nicht die gleiche Wirkung wie jQuery. Während ich versuchte, der Anleitung zum Ändern von angular $httpprovider zu folgen, stieß ich auf andere Probleme. Z.B. Ich benutze einen Codeigner, in dem die Funktion $this->input->is_ajax_request() immer fehlgeschlagen ist (was von einem anderen Programmierer geschrieben und global verwendet wurde, kann also nicht geändert werden) und sagte, dies sei keine echte Ajax-Anforderung.

Um es zu lösen, nahm ich die Hilfe von aufgeschobenes Versprechen . Ich habe es in Firefox und IE9 getestet und es hat funktioniert.

Ich habe folgende Funktion definiert außerhalb eines der angular Codes. Diese Funktion ruft regelmäßig jquery ajax auf und gibt das verzögerte/versprechende (ich lerne noch) Objekt zurück.

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

Dann nenne ich es angular Code mit dem folgenden Code. Bitte beachten Sie, dass wir den $scope manuell mit $scope.$apply() aktualisieren müssen.

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

Dies mag nicht die perfekte Antwort sein, aber es erlaubte mir, jquery-Ajax-Aufrufe mit angular zu verwenden und erlaubte mir, den $scope zu aktualisieren.

3
Nis

Wenn Sie Angular> = 1.4 verwenden, ist dies die sauberste Lösung mit dem von Angular bereitgestellten Serializer :

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

Und dann können Sie dies einfach überall in Ihrer App tun:

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

Außerdem werden die Daten korrekt als param1=value1&param2=value2 serialisiert und mit dem Header /requesturl Content-Type an application/x-www-form-urlencoded; charset=utf-8 gesendet, wie dies normalerweise bei POST Anforderungen an Endpunkten erwartet wird.

TL; DR

Während meiner Recherche fand ich heraus, dass die Antwort auf dieses Problem in vielen verschiedenen Varianten vorliegt. Einige sind sehr kompliziert und hängen von benutzerdefinierten Funktionen ab, andere hängen von jQuery ab, und andere weisen unvollständig darauf hin, dass Sie nur den Header festlegen müssen.

Wenn Sie nur den Header Content-Type festlegen, werden für den Endpunkt die Daten POST angezeigt, die jedoch nicht im Standardformat vorliegen, es sei denn, Sie geben eine Zeichenfolge als data an. Wenn Sie Ihr Datenobjekt manuell serialisieren, wird es standardmäßig als JSON serialisiert und möglicherweise am Endpunkt falsch interpretiert.

z.B. Wenn im obigen Beispiel nicht der richtige Serializer festgelegt wurde, wird er auf dem Endpunkt wie folgt angezeigt:

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

Und das kann zu unerwartetem Parsen führen, z. ASP.NET behandelt es als null -Parameternamen mit {"param1":"value1","param2":"value2"} als Wert. oder Fiddler interpretiert es anders, mit {"param1":"value1","param2":"value2"} als Parameternamen und null als Wert.

3
Saeb Amini

Wenn Sie PHP verwenden, ist dies eine einfache Möglichkeit, über einen AngularJS-POST auf ein Array in PHP zuzugreifen.

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

Ich verwende asp.net WCF-Webservices mit angular js und dem folgenden Code:

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

Ich hoffe es hilft.

3
Mehdi Rostami

Es wurde kein vollständiges Code-Snippet gefunden, das beschreibt, wie mit der $ http.post-Methode Daten an den Server gesendet werden und warum dies in diesem Fall nicht funktioniert hat.

Erklärungen zum folgenden Code-Snippet ...

  1. Ich verwende die Funktion jQuery $ .param, um die JSON-Daten in WWW-Post-Daten zu serialisieren
  2. Festlegen des Inhaltstyps in der Konfigurationsvariablen, die zusammen mit der Anfrage von angleJS $ http.post übergeben wird, die den Server anweist, dass Daten im WWW-Post-Format gesendet werden.

  3. Beachten Sie die Methode $ htttp.post, bei der ich den ersten Parameter als URL, den zweiten Parameter als Daten (serialisiert) und den dritten Parameter als Konfiguration sende.

Der verbleibende Code versteht sich von selbst.

$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 +
                    "<hr />status: " + status +
                    "<hr />headers: " + header +
                    "<hr />config: " + config;
            });
        };

Schauen Sie sich hier das Codebeispiel der $ http.post-Methode an .

3
Sheo Narayan

Ähnlich wie das vom OP vorgeschlagene Arbeitsformat und die Antwort von Denison, außer dass $http.post anstelle von $http verwendet wird und weiterhin von jQuery abhängig ist.

Das Gute an der Verwendung von jQuery ist, dass komplexe Objekte ordnungsgemäß übergeben werden. gegen manuelles Konvertieren in URL-Parameter, die die Daten verfälschen könnten.

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

Ich hatte das gleiche Problem in Express .. Um zu beheben, müssen Sie Bodyparser verwenden, um JSON-Objekte zu analysieren, bevor Sie http-Anforderungen senden ..

app.use(bodyParser.json());
3

Gerade von angular 1.2 auf 1.3 aktualisiert, habe ein Problem im Code gefunden. Das Transformieren einer Ressource führt zu einer Endlosschleife, da (glaube ich) das Versprechen von $ wieder dasselbe Objekt enthält. Vielleicht hilft es jemandem ...

Ich könnte das beheben, indem ich:

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

Ich verwende seit einiger Zeit den akzeptierten Antwortcode (Felipes Code) und er funktioniert hervorragend (danke, Felipe!).

Vor kurzem habe ich jedoch festgestellt, dass es Probleme mit leeren Objekten oder Arrays gibt. Zum Beispiel, wenn Sie dieses Objekt einreichen:

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

PHP scheint B und C überhaupt nicht zu sehen. Das bekommt es:

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

Ein Blick auf die aktuelle Anfrage in Chrome zeigt Folgendes:

A: 1
:
D: 2

Ich habe ein alternatives Code-Snippet geschrieben. Es scheint gut mit meinen Anwendungsfällen zu funktionieren, aber ich habe es nicht ausgiebig getestet, also benutze es mit Vorsicht.

Ich habe TypeScript verwendet, weil ich starke Typisierung mag, aber es wäre einfach, in reines JS zu konvertieren:

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
    (<any>$httpProvider.defaults).transformRequest = [ function(data: any) {
        if (!angular.isObject(data) || data.toString() == "[object File]") return data;
        return phpize(data).join("&");
    } ];
} ]);

Es ist weniger effizient als Felipes Code, aber ich denke nicht, dass es wichtig ist, da es im Vergleich zum Gesamtaufwand der HTTP-Anforderung selbst unmittelbar sein sollte.

Nun zeigt PHP:

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

Soweit ich weiß, ist es nicht möglich, PHP zu bekommen, um zu erkennen, dass Ba und C leere Arrays sind, aber es erscheinen zumindest die Schlüssel im wesentlichen innen leer.

Beachten Sie auch, dass ndefined s und null s in leere Zeichenfolgen konvertiert werden.

2
obe

Als ich dieses Problem hatte, stellte sich heraus, dass der Parameter, den ich postete, ein Array von Objekten anstelle eines einfachen Objekts war.

2
D. Kermott

Es ist nicht Winkels Schuld. Angular funktioniert in der JSON-Welt. Wenn also ein $ http-Dienst eine AJAX -Anforderung sendet, werden alle Ihre Daten als Nutzdaten und nicht als Formulardaten gesendet, damit Ihre Back-End-Anwendung damit umgehen kann. Aber jQuery macht einige Dinge intern. Sie weisen das $ ajax-Modul von jQuery an, Formulardaten als JSON zu binden. Bevor Sie jedoch eine AJAX -Anforderung senden, serialisieren Sie JSON und fügen den application/x-www-form-urlencoded -Header hinzu. Auf diese Weise kann Ihre Backend-Anwendung Formulardaten in Form von Post-Parametern und nicht in Form von JSON empfangen.

Sie können das Standardverhalten des angular $ http-Diensts jedoch durch ändern

  1. Header hinzufügen
  2. Json wird serialisiert

$ httpParamSerializerJQLike ist der eingebaute Dienst von angle, der json auf die gleiche Weise serialisiert wie jQuery mit $ .param.

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

Wenn Sie ein Plugin benötigen, um Formulardaten zuerst in JSON zu serialisieren, verwenden Sie dieses https://github.com/marioizquierdo/jquery.serializeJSON

1
Uday Hiwarale

Geben Sie einfach die Daten, die Sie senden möchten, als zweiten Parameter ein:

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

Eine andere Form, die auch funktioniert, ist:

$http.post('request-url',  { params: { paramName: value } });

Stellen Sie sicher, dass paramName genau mit dem Namen des Parameters der aufgerufenen Funktion übereinstimmt.

Quelle: AngularJS-Post-Shortcut-Methode

1
Marco Lackovic

Ich habe das durch die folgenden Codes gelöst:

Client-Seite (Js):

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

beachten Sie, dass Daten ein Objekt sind.

Auf dem Server (ASP.NET MVC):

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

            return data.methodName;
        }

und 'AllowCrossSiteJsonAttribute' wird für domänenübergreifende Anforderungen benötigt:

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

Hoffe das war nützlich.

1
pixparker

Ich habe ein kleines PHP-Hilfsfunktion geschrieben, das beide Arten von Eingabeparametern erlaubt:

function getArgs () {
    if ($input = file_get_contents('php://input') && $input_params = json_decode($input,true))
        return $input_params + $_POST + $_GET;
    return $_POST + $_GET;
}

Verwendungszweck :

<?php
    include("util.php"); # above code
    $request = getArgs();

    $myVar = "";
    if (isset($request['myVar']))
        $myVar = $request['myVar'];
?>

Daher sind keine Änderungen an Ihrem JavaScript erforderlich.

0
Craig Smedley

Ich hatte dieses Problem, das Problem war, dass ich die Daten beim Posten unter Verwendung des oben genannten Headers nicht abrufen konnte, d. H.

headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/x-www-form-urlencoded'
}

Während der Verwendung von jquery Ajax wurden normalerweise Daten in response.body auf dem Back-End-Server abgerufen, aber während der Implementierung von Angular Ajax kamen die Daten nicht in response.body, sondern unter

request.getParameterMap.keySet().iterator().next()
0
John Swain

Fand die einfache Lösung auf

http://jasonwatmore.com/post/2014/04/18/post-a-simple-string-value-from-angularjs-to-net-web-api

return $http.post(Config.apiUrl + '/example/processfile', '"' + fileName + '"');
0
NoloMokgosi

Schlage einfach eine modernisierte Version von @ FelipeMiossos Antwort vor :

.config(["$httpProvider", function ($httpProvider) {

  function buildKey(parentKey, subKey) {
    return parentKey + "[" + subKey + "]";
  }

  function buildObject(key, value) {
    var object = {};
    object[key] = value;
    return object;
  }

  function join(array) {
    return array.filter(function (entry) {
      return entry;
    }).join("&");
  }

  function arrayToQueryString(parentKey, array) {
    return join(array.map(function (value, subKey) {
      return toQueryString(buildObject(buildKey(parentKey, subKey), value));
    }));
  }

  function objectToQueryString(parentKey, object) {
    return join(Object.keys(object).map(function (subKey) {
      return toQueryString(buildObject(buildKey(parentKey, subKey), object[subKey]));
    }));
  }

  function toQueryString(input) {
    return join(Object.keys(input).map(function (key) {
      var value = input[key];
      if (value instanceof Array) {
        return arrayToQueryString(key, value);
      } else if (value instanceof Object) {
        return objectToQueryString(key, value);
      } else if (undefined !== value && null !== value) {
        return encodeURIComponent(key) + "=" + encodeURIComponent(value);
      } else {
        return "";
      }
    }));
  }

  function isQueryStringEligible(input) {
    return null !== input && "object" === typeof input && "[object File]" !== String(input);
  }

  var interceptor = [function () {
    return {
      request: function (config) {
        if (0 <= ["post", "put", "patch"].indexOf(config.method.toLowerCase()) && isQueryStringEligible(config.data)) {
          config.headers["Content-Type"] = "application/x-www-form-urlencoded;charset=utf-8";
          config.data = toQueryString(config.data);
        }
        return config;
      }
    };
  }];

  $httpProvider.interceptors.Push(interceptor);

}])

ES6-Version:

.config(["$httpProvider", function ($httpProvider) {

  "use strict";

  const buildKey = (parentKey, subKey) => `${parentKey}[${subKey}]`;

  const buildObject = (key, value) => ({ [key]: value });

  const join = (array) => array.filter((entry) => entry).join("&");

  const arrayToQueryString = (parentKey, array) =>
    join(array.map((value, subKey) =>
      toQueryString(buildObject(buildKey(parentKey, subKey), value))));

  const objectToQueryString = (parentKey, object) =>
    join(Object.keys(object).map((subKey) =>
      toQueryString(buildObject(buildKey(parentKey, subKey), object[subKey]))));

  const toQueryString = (input) => join(Object.keys(input).map((key) => {
    const value = input[key];
    if (value instanceof Array) {
      return arrayToQueryString(key, value);
    } else if (value instanceof Object) {
      return objectToQueryString(key, value);
    } else if (undefined !== value && null !== value) {
      return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
    } else {
      return "";
    }
  }));

  const isQueryStringEligible = (input) =>
    null !== input && "object" === typeof input && "[object File]" !== String(input);

  const interceptor = [() => ({
    request(config) {
      if (0 <= ["post", "put", "patch"].indexOf(config.method.toLowerCase()) && isQueryStringEligible(config.data)) {
        config.headers["Content-Type"] = "application/x-www-form-urlencoded;charset=utf-8";
        config.data = toQueryString(config.data);
      }
      return config;
    }
  })];

  $httpProvider.interceptors.Push(interceptor);

}])
0
sp00m

benutze diesen Weg. Du musst nicht so viel schreiben

 isAuth = $http.post("Yr URL", {username: username, password: password});

und im NodeJS-Backend

app.post("Yr URL",function(req,resp)
{

  var username = req.body.username||req.param('username');
  var password = req.body.password||req.param('password');
}

Ich hoffe das hilft

0
Siddharth

Mit einer sehr einfachen Methode können wir dies befolgen:

 $http({
        url : "submit_form_adv.php",
        method : 'POST',
        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 : {sample_id : 100, sample_name: 'Abin John'},

    }).success(function(data, status, headers, config) {

    }).error(function(ata, status, headers, config) {

    });
0
Hari