it-swarm.com.de

AngularJS - Gibt es eine Möglichkeit, dass $ http.post Anforderungsparameter anstelle von JSON sendet?

Ich habe einen alten Code, der eine AJAX POST - Anforderung über die Post-Methode von jQuery erstellt und in etwa so aussieht:

$.post("/foo/bar", requestData,
    function(responseData)
    {
        //do stuff with response
    }

requestData ist nur ein Javascript-Objekt mit einigen grundlegenden Zeichenfolgeeigenschaften.

Ich bin gerade dabei, unsere Sachen zur Verwendung von Angular zu verschieben, und ich möchte diesen Aufruf durch $ http.post ersetzen. Ich habe mir folgendes ausgedacht:

$http.post("/foo/bar", requestData).success(
    function(responseData) {
        //do stuff with response
    }
});

Als ich dies tat, erhielt ich eine 500-Fehlerantwort vom Server. Mit Firebug habe ich festgestellt, dass der Anfragetext wie folgt gesendet wurde:

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

Die erfolgreiche jQuery $.post sendet den Body folgendermaßen:

param1=value1&param2=value2&param3=value3

Der Endpunkt, den ich anschlage, erwartet Anforderungsparameter und nicht JSON. Meine Frage ist also, dass es $http.post sowieso anweist, das Javascript-Objekt als Anforderungsparameter anstelle von JSON zu senden. Ja, ich weiß, ich könnte die Zeichenfolge selbst aus dem Objekt konstruieren, aber ich möchte wissen, ob Angular aus der Box heraus irgendetwas bereitstellt.

116
dnc253

Ich denke, dass der Parameter params config hier nicht funktioniert, da er die Zeichenfolge anstelle des Hauptteils der URL hinzufügt, aber was hier vorgeschlagen wird, ist ein Beispiel für die globale Überschreibung einer Standardtransformation (mithilfe von jQuery -param als Beispiel zum Konvertieren der Daten in eine Parameterzeichenfolge).

Globale transformRequest-Funktion einrichten:

var app = angular.module('myApp');

app.config(function ($httpProvider) {
    $httpProvider.defaults.transformRequest = function(data){
        if (data === undefined) {
            return data;
        }
        return $.param(data);
    }
});

Auf diese Weise wird bei allen Aufrufen von $ http.post der Text automatisch in dasselbe Parameterformat umgewandelt, das für den Aufruf von jQuery $.post verwendet wird.

Beachten Sie, dass Sie den Content-Type-Header auch pro Aufruf oder global wie folgt festlegen möchten:

$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';

Beispiel für nicht globale Transformationsanforderung pro Aufruf:

    var transform = function(data){
        return $.param(data);
    }

    $http.post("/foo/bar", requestData, {
        headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
        transformRequest: transform
    }).success(function(responseData) {
        //do stuff with response
    });
140
Gloopy

Bei Verwendung von Angular> = 1.4 ist hier die sauberste Lösung, die ich gefunden habe und die nicht auf benutzerdefinierte oder externe Elemente angewiesen ist:

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 das überall in Ihrer App tun:

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

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

20
Saeb Amini

Aus der AngularJS-Dokumentation:

params - {Object.} - Map von Strings oder Objekten, die wird auf? key1 = value1 & key2 = value2 nach der URL umgestellt. Wenn die value ist keine Zeichenfolge, es wird JSONified.

Geben Sie als Parameter string an. Wenn Sie das nicht möchten, verwenden Sie Transformationen. Wieder aus der Dokumentation:

Um diese Umwandlung lokal zu überschreiben, geben Sie die Umwandlungsfunktionen an als transformRequest- und/oder transformResponse-Eigenschaften der config Objekt. Um die Standardumwandlungen global zu überschreiben, überschreiben Sie die $ httpProvider.defaults.transformRequest und $ httpProvider.defaults.transformResponse-Eigenschaften von $ httpProvider.

Weitere Informationen finden Sie in Dokumentation .

17
Infeligo

Verwenden Sie die $.param-Funktion von jQuery, um die JSON-Daten in requestData zu serialisieren.

Kurz gesagt, verwenden Sie ähnlichen Code wie Ihren:

$http.post("/foo/bar",
$.param(requestData),
{
    headers:
    {
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
    }
}
).success(
    function(responseData) {
        //do stuff with response
    }
});

Zu diesem Zweck müssen Sie jQuery zusammen mit AngularJS in Ihre Seite aufnehmen.

15
Sagar Bhosale

Beachten Sie, dass Sie ab Angular 1.4 die Formulardaten ohne jQuery serialisieren können.

In der app.js:

module.run(function($http, $httpParamSerializerJQLike) {
  $http.defaults.transformRequest.unshift($httpParamSerializerJQLike);
});

Dann in Ihrem Controller:

$http({
    method: 'POST',
    url: myUrl',
    headers: {'Content-Type': 'application/x-www-form-urlencoded'},
    data: myData
});
7
Thomas Graziani

Ich habe auch Probleme mit der Einstellung der benutzerdefinierten http-Authentifizierung, da die Ressource $ resource die Anforderung zwischenspeichert.

Damit es funktioniert, müssen Sie die vorhandenen Kopfzeilen auf diese Weise überschreiben 

var transformRequest = function(data, headersGetter){
  var headers = headersGetter();
  headers['Authorization'] = 'WSSE profile="UsernameToken"';
  headers['X-WSSE'] = 'UsernameToken ' + nonce
  headers['Content-Type'] = 'application/json';
};

return $resource(
  url,
    {
    },
    {
      query: {
        method: 'POST',
        url: apiURL + '/profile',
        transformRequest: transformRequest,
        params: {userId: '@userId'}
      },
    }
);

Ich hoffe ich konnte jemandem helfen. Ich habe 3 Tage gebraucht, um das herauszufinden.

5
Frank Marcelo

Dies mag ein bisschen hacken, aber ich habe das Problem vermieden und den Json in das POST - Array von PHP auf der Serverseite umgewandelt:

$_POST = json_decode(file_get_contents('php://input'), true);
5
TimoSolo

Ändern Sie die Standardheader:

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

Dann verwenden Sie die $.param-Methode von JQuery:

var payload = $.param({key: value});
$http.post(targetURL, payload);
4
Zags
   .controller('pieChartController', ['$scope', '$http', '$httpParamSerializerJQLike', function($scope, $http, $httpParamSerializerJQLike) {
        var data = {
                TimeStamp : "2016-04-25 12:50:00"
        };
        $http({
            method: 'POST',
            url: 'serverutilizationreport',
            headers: {'Content-Type': 'application/x-www-form-urlencoded'},
            data: $httpParamSerializerJQLike(data),
        }).success(function () {});
    }
  ]);
3
Rohit Luthra

Schnelle Anpassung - Für alle, die Probleme mit der globalen Konfiguration der transformRequest-Funktion haben, ist hier der Ausschnitt, den ich verwende, um den Cannot read property 'jquery' of undefined-Fehler zu beseitigen:

$httpProvider.defaults.transformRequest = function(data) {
        return data != undefined ? $.param(data) : null;
    }
2
kshep92

Sie können dieses Problem auch lösen, ohne den Code im Server zu ändern, den Header im $http.post-Aufruf zu ändern und $_POST wie gewohnt zu verwenden. Erklärt hier: http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/

1
vikramaditya234

Ich habe oft problematische Verhaltensweisen gefunden. Ich habe es aus express (ohne Typisierung) und dem bodyParser (mit den dt ~ Body-Parser-Typisierungen) verwendet.

Ich habe nicht versucht, eine Datei hochzuladen, sondern einfach eine in einem Post-String angegebene JSON zu interpretieren.

Der request.body war einfach ein leerer Json ({}).

Nach langen Nachforschungen hat das endlich für mich funktioniert:

import { json } from 'body-parser';
...
app.use(json()); <-- should be defined before the first POST handler!

Es kann auch wichtig sein, den Inhaltstyp application/json in der Anforderungszeichenfolge von der Clientseite aus anzugeben.

0
peterh

Syntax für AngularJS v1.4.8 + (v1.5.0)

       $http.post(url, data, config)
            .then(
                    function (response) {
                        // success callback
                    },
                    function (response) {
                        // failure callback
                    }
            );

Z.B:

    var url = "http://example.com";

    var data = {
        "param1": "value1",
        "param2": "value2",
        "param3": "value3"
    };

    var config = {
        headers: {
            'Content-Type': "application/json"
        }
    };

    $http.post(url, data, config)
            .then(
                    function (response) {
                        // success callback
                    },
                    function (response) {
                        // failure callback
                    }
            );
0
Pranav V R