ajax - titel - wordpress title tag ändern




Wie kann ich Daten als Formulardaten anstelle einer Anforderungsnutzlast posten? (14)

Im folgenden Code ruft die AngularJS $http Methode die URL auf und übergibt das xsrf-Objekt als "Request Payload" (wie auf der Registerkarte des Chrome-Debugger-Netzwerks beschrieben). Die Methode jQuery $.ajax führt den gleichen Aufruf aus, übergibt jedoch xsrf als "Formulardaten".

Wie kann ich AngularJS dazu bringen, xsrf als Formulardaten anstelle einer Anforderungsnutzlast zu senden?

var url = 'http://somewhere.com/';
var xsrf = {fkey: 'xsrf key'};

$http({
    method: 'POST',
    url: url,
    data: xsrf
}).success(function () {});

$.ajax({
    type: 'POST',
    url: url,
    data: xsrf,
    dataType: 'json',
    success: function() {}
});

Ab AngularJS v1.4.0 gibt es einen integrierten $httpParamSerializer Dienst, der jedes Objekt gemäß den Regeln, die auf der Dokumentseite aufgelistet sind, in einen Teil einer HTTP-Anfrage konvertiert.

Es kann so verwendet werden:

$http.post('http://example.com', $httpParamSerializer(formDataObj)).
    success(function(data){/* response status 200-299 */}).
    error(function(data){/* response status 400-999 */});

Denken Sie daran, dass für einen korrekten Formular-Post der Content-Type Header geändert werden muss. Um dies global für alle POST-Anfragen zu tun, kann dieser Code (aus der Halbantwort von Albireo) verwendet werden:

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

Um dies nur für den aktuellen Post zu tun, muss die headers Eigenschaft des Request-Objekts geändert werden:

var req = {
 method: 'POST',
 url: 'http://example.com',
 headers: {
   'Content-Type': 'application/x-www-form-urlencoded'
 },
 data: $httpParamSerializer(formDataObj)
};

$http(req);

Als Workaround können Sie den Code, der den POST empfängt, einfach dazu veranlassen, auf application / json-Daten zu reagieren. Für PHP habe ich den folgenden Code hinzugefügt, damit ich ihn entweder in Form-Encoded oder JSON POST kann.

//handles JSON posted arguments and stuffs them into $_POST
//angular's $http makes JSON posts (not normal "form encoded")
$content_type_args = explode(';', $_SERVER['CONTENT_TYPE']); //parse content_type string
if ($content_type_args[0] == 'application/json')
  $_POST = json_decode(file_get_contents('php://input'),true);

//now continue to reference $_POST vars as usual

Die anhaltende Verwirrung, die dieses Thema umgibt, inspirierte mich dazu, einen Blogbeitrag darüber zu schreiben. Die Lösung, die ich in diesem Beitrag vorschlage, ist besser als Ihre aktuelle Top-Lösung, da Sie nicht darauf beschränkt ist, Ihr Datenobjekt für $ http-Serviceaufrufe zu parametrisieren; Dh mit meiner Lösung können Sie einfach weiterhin tatsächliche Datenobjekte an $ http.post () usw. übergeben und trotzdem das gewünschte Ergebnis erzielen.

Außerdem basiert die am besten bewertete Antwort auf der Aufnahme von vollständiger jQuery in die Seite für die $ .param () - Funktion, während meine Lösung jQuery agnostic ist, pure AngularJS ready.

http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/

Hoffe das hilft.


Die einzige Thin, die Sie ändern müssen, ist die Eigenschaft "params" anstelle von "data" zu verwenden, wenn Sie Ihr $ http-Objekt erstellen:

$http({
   method: 'POST',
   url: serviceUrl + '/ClientUpdate',
   params: { LangUserId: userId, clientJSON: clients[i] },
})

Im obigen Beispiel ist clients [i] nur ein JSON-Objekt (in keiner Weise serialisiert). Wenn Sie "params" anstelle von "data" verwenden, wird angular das Objekt für Sie mit $ httpParamSerializer serialisieren: https://docs.angularjs.org/api/ng/service/ $ httpParamSerializer


Dies ist keine direkte Antwort, sondern eine etwas andere Designrichtung:

Veröffentlichen Sie die Daten nicht als Formular, sondern als JSON-Objekt, das direkt dem serverseitigen Objekt zugeordnet werden soll, oder verwenden Sie die REST-Formatpfadvariable

Jetzt weiß ich, dass keine Option in Ihrem Fall geeignet sein könnte, da Sie versuchen, einen XSRF-Schlüssel zu übergeben. Es in eine Pfadvariable wie diese zu mappen ist ein schreckliches Design:

http://www.someexample.com/xsrf/{xsrfKey}

Da Sie von Natur aus den xsrf-Schlüssel auch an einen anderen Pfad übergeben möchten, /login , /book-appointment termination usw., und Sie möchten Ihre hübsche URL nicht durcheinander bringen

Interessanterweise ist es auch nicht sinnvoll, es als Objektfeld hinzuzufügen, denn jetzt müssen Sie für jedes json-Objekt, das Sie an den Server übergeben, das Feld hinzufügen

{
  appointmentId : 23,
  name : 'Joe Citizen',
  xsrf : '...'
}

Sie möchten sicherlich kein weiteres Feld auf Ihrer serverseitigen Klasse hinzufügen, das nicht direkt mit dem Domänenobjekt semantisch verbunden ist.

Meiner Meinung nach ist der beste Weg, Ihren xsrf-Schlüssel über einen HTTP-Header zu übergeben. Viele xsrf-Schutz serverseitige Web-Framework-Bibliothek unterstützen dies. In Java Spring können Sie sie beispielsweise mit dem X-CSRF-TOKEN Header übergeben .

Angulars ausgezeichnete Fähigkeit, JS-Objekte an UI-Objekte zu binden, bedeutet, dass wir die Praxis, alle Formulare zusammenzustellen, loswerden und stattdessen JSON veröffentlichen können. JSON kann leicht in serverseitige Objekte deserialisiert werden und komplexe Datenstrukturen wie Karten, Arrays, verschachtelte Objekte usw. unterstützen.

Wie postet man Array in einer Form-Payload? Vielleicht so:

shopLocation=downtown&daysOpen=Monday&daysOpen=Tuesday&daysOpen=Wednesday

oder dieses:

shopLocation=downtwon&daysOpen=Monday,Tuesday,Wednesday

Beide sind schlechtes Design ..


Diese Antworten sehen aus wie wahnsinniger Overkill, manchmal ist einfach einfach besser:

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

Es gibt ein wirklich nettes Tutorial, das über dieses und andere verwandte Dinge geht - Einreichen von AJAX-Formularen: Der AngularJS-Weg .

Im Grunde müssen Sie den Header der POST-Anforderung so einstellen, dass Sie angeben, dass Sie Formulardaten als URL-codierte Zeichenfolge senden, und die zu sendenden Daten im selben Format festlegen

$http({
  method  : 'POST',
  url     : 'url',
  data    : $.param(xsrf),  // pass in data as strings
  headers : { 'Content-Type': 'application/x-www-form-urlencoded' }  // set the headers so angular passing info as form data (not request payload)
});

Beachten Sie, dass die Hilfsfunktion param () von jQuery hier zum Serialisieren der Daten in eine Zeichenfolge verwendet wird. Sie können dies jedoch auch manuell tun, wenn Sie jQuery nicht verwenden.


Für Symfony2 Benutzer:

Wenn Sie nichts in Ihrem Javascript ändern möchten, können Sie diese Änderungen in Ihrer Symfony App vornehmen:

Erstellen Sie eine Klasse, die Symfony \ Component \ HttpFoundation \ Request-Klasse erweitert:

<?php

namespace Acme\Test\MyRequest;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\ParameterBag;

class MyRequest extends Request{


/**
* Override and extend the createFromGlobals function.
* 
* 
*
* @return Request A new request
*
* @api
*/
public static function createFromGlobals()
{
  // Get what we would get from the parent
  $request = parent::createFromGlobals();

  // Add the handling for 'application/json' content type.
  if(0 === strpos($request->headers->get('CONTENT_TYPE'), 'application/json')){

    // The json is in the content
    $cont = $request->getContent();

    $json = json_decode($cont);

    // ParameterBag must be an Array.
    if(is_object($json)) {
      $json = (array) $json;
  }
  $request->request = new ParameterBag($json);

}

return $request;

}

}

Verwenden Sie nun Ihre Klasse in app_dev.php (oder einer von Ihnen verwendeten Indexdatei)

// web/app_dev.php

$kernel = new AppKernel('dev', true);
// $kernel->loadClassCache();
$request = ForumBundleRequest::createFromGlobals();

// use your class instead
// $request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);

Ich verwende derzeit die folgende Lösung, die ich in der AngularJS google group gefunden habe.

$http
.post('/echo/json/', 'json=' + encodeURIComponent(angular.toJson(data)), {
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
    }
}).success(function(data) {
    $scope.data = data;
});

Beachten Sie, dass Sie, wenn Sie PHP verwenden, etwas wie den Request::createFromGlobals() Symfony 2 HTTP-Komponente verwenden Request::createFromGlobals() , um dies zu lesen, da $ _POST nicht automatisch damit geladen wird.


In deiner App-Konfiguration -

$httpProvider.defaults.transformRequest = function (data) {
        if (data === undefined)
            return data;
        var clonedData = $.extend(true, {}, data);
        for (var property in clonedData)
            if (property.substr(0, 1) == '$')
                delete clonedData[property];

        return $.param(clonedData);
    };

Mit Ihrer Ressourcenanforderung -

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

Sie können das Verhalten global definieren:

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

Sie müssen es also nicht jedes Mal neu definieren:

$http.post("/handle/post", {
    foo: "FOO",
    bar: "BAR"
}).success(function (data, status, headers, config) {
    // TODO
}).error(function (data, status, headers, config) {
    // TODO
});

Sie können mit der untenstehenden Lösung versuchen

$http({
        method: 'POST',
        url: url-post,
        data: data-post-object-json,
        headers: {'Content-Type': 'application/x-www-form-urlencoded'},
        transformRequest: function(obj) {
            var str = [];
            for (var key in obj) {
                if (obj[key] instanceof Array) {
                    for(var idx in obj[key]){
                        var subObj = obj[key][idx];
                        for(var subKey in subObj){
                            str.push(encodeURIComponent(key) + "[" + idx + "][" + encodeURIComponent(subKey) + "]=" + encodeURIComponent(subObj[subKey]));
                        }
                    }
                }
                else {
                    str.push(encodeURIComponent(key) + "=" + encodeURIComponent(obj[key]));
                }
            }
            return str.join("&");
        }
    }).success(function(response) {
          /* Do something */
        });

Vollständige Antwort (seit Winkel 1.4). Sie müssen die Abhängigkeit $ httpParamSerializer einschließen

var res = $resource(serverUrl + 'Token', { }, {
                save: { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }
            });

            res.save({ }, $httpParamSerializer({ param1: 'sdsd', param2: 'sdsd' }), function (response) {

            }, function (error) { 

            });

Wenn Sie jQuery nicht in der Lösung verwenden möchten, können Sie dies versuchen. Lösung nabbed von hier https://.com/a/1714899/1784301

$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: xsrf
}).success(function () {});




angular-http