IT-Swarm.Net

Kako mogu objaviti podatke u obliku podataka umjesto opterećenja zahtjeva zahtjeva?

U donjem kôdu, metoda AngularJS $http poziva URL, a objekt xsrf podnosi kao "Zahtjev za opterećenje" (kao što je opisano na kartici mreže za uklanjanje pogrešaka Chrome). Metoda jQuery $.ajax radi isti poziv, ali xsrf podnosi kao "Podaci podataka".

Kako mogu navesti AngularJS da pošalje xsrf kao podatke obrasca umjesto korisničkog opterećenja zahtjeva?

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

Sljedećem retku treba dodati objekt $ $ koji je proslijeđen:

headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}

A preneseni podaci trebaju se pretvoriti u niz kodirani URL-om:

> $.param({fkey: "key"})
'fkey=key'

Dakle, imate nešto poput:

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

From: https://groups.google.com/forum/#!msg/angular/5nAedJ1LyO0/4Vj_72EZcDsJ

AŽURIRANJE

Za korištenje novih usluga dodanih s AngularJS V1.4, vidi

601
mjibson

Ako ne želite koristiti jQuery u rješenju, pokušajte ovo. Rješenje se odavde https://stackoverflow.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 () {});
192
Anthony

Trajna zbrka oko ove problematike potaknula me na pisanje bloga o tome. Rješenje koje predlažem u ovom postu je bolje od vašeg trenutačno najbolje ocijenjenog rješenja jer vas ne ograničava u podešavanju vašeg podatkovnog objekta za $ http uslužne pozive; tj. mojim rješenjem možete jednostavno nastaviti prosljeđivati ​​stvarne podatke s podacima na $ http.post () itd. i dalje postići željeni rezultat.

Također, najbolje ocijenjeni odgovor oslanja se na uključivanje punog jQueryja u stranicu za funkciju $ .param (), dok je moje rješenje jQuery agnostic, čist AngularJS spreman.

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

Nadam se da ovo pomaže.

91
Ezekiel Victor

Uzeo sam nekoliko drugih odgovora i napravio nešto malo čistije, stavio ovaj .config() poziv na kraj vašeg kutnog modula u vašu app.js:

.config(['$httpProvider', function ($httpProvider) {
  // Intercept POST requests, convert to standard form encoding
  $httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
  $httpProvider.defaults.transformRequest.unshift(function (data, headersGetter) {
    var key, result = [];

    if (typeof data === "string")
      return data;

    for (key in data) {
      if (data.hasOwnProperty(key))
        result.Push(encodeURIComponent(key) + "=" + encodeURIComponent(data[key]));
    }
    return result.join("&");
  });
}]);
82
kzar

Od AngularJS v1.4.0, postoji ugrađena usluga $httpParamSerializer koja pretvara bilo koji objekt u dio HTTP zahtjeva prema pravilima koja su navedena na stranici dokumenata .

Može se koristiti na ovaj način:

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

Zapamtite da se za ispravan post u obliku zaglavlje Content-Type mora promijeniti. Da biste to učinili globalno za sve POST zahtjeve, može se upotrijebiti ovaj kôd (preuzet iz Albireoovog pola odgovora):

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

Da biste to učinili samo za trenutni post, potrebno je izmijeniti svojstvo headers u zahtjevu-objektu:

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

$http(req);
57
Mitja

Globalno možete definirati ponašanje:

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

Dakle, ne morate je redefinirati svaki put:

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

Kao zaobilazno rješenje možete jednostavno izvršiti kod koji prima POST odgovor na aplikaciju/json podatke. Za PHP Dodao sam šifru u nastavku, omogućujući mi da POST u bilo koji oblik ili JSON.

//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
20
James Bell

Ovi odgovori izgledaju kao suludo pretjerano korištenje, ponekad je jednostavno još bolje:

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

Možete isprobati s donjim rješenjem

$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 */
        });
9
tmquang6805

Izradite uslugu adaptera za post:

services.service('Http', function ($http) {

    var self = this

    this.post = function (url, data) {
        return $http({
            method: 'POST',
            url: url,
            data: $.param(data),
            headers: {'Content-Type': 'application/x-www-form-urlencoded'}
        })
    }

}) 

Upotrijebite ga u svojim kontrolerima ili bilo što već:

ctrls.controller('PersonCtrl', function (Http /* our service */) {
    var self = this
    self.user = {name: "Ozgur", eMail: null}

    self.register = function () {
        Http.post('/user/register', self.user).then(function (r) {
            //response
            console.log(r)
        })
    }

})
8
Ozgur

Postoji stvarno lijep udžbenik koji ide preko ove i drugih srodnih stvari - slanje AJAX oblici: način AngularJS .

U osnovi morate postaviti zaglavlje POST zahtjeva da naznačite da šaljete podatke obrasca kao niz kodirani URL-om i da postavite podatke da se šalju u istom formatu

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

Imajte na umu da se ovdje pomoćna funkcija jQuery param () koristi za serijsku seriju podataka u nizu, ali to možete učiniti i ručno, ako ne koristite jQuery.

7
robinmitra
var fd = new FormData();
    fd.append('file', file);
    $http.post(uploadUrl, fd, {
        transformRequest: angular.identity,
        headers: {'Content-Type': undefined}
    })
    .success(function(){
    })
    .error(function(){
    });

Molimo naplatite! https://uncorkedstudios.com/blog/multipartformdata-file-upload-with-angularjs

6
aul

Za korisnike Symfony2:

Ako ne želite ništa mijenjati u vašem JavaScriptu da bi ovo radilo, napravite sljedeće izmjene u aplikaciji Symfony:

Napravite klasu koja se proširuje na Symfony\Component\HttpFoundation\Request klasu:

<?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;

}

}

Sada koristite klasu u app_dev.php (ili bilo kojoj indeksnoj datoteci koju koristite)

// 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);
4
carmel

Trenutno koristim sljedeće rješenje I pronađeno u Googleovoj grupi AngularJS.

 $ http 
. post ('/ echo/json /', 'json =' + encodeURIComponent (angular.toJson (podaci)), {
 zaglavlja: {
 'Vrsta sadržaja': 'aplikacija/x-www-form-urlencoded; charset = UTF-8' 
} 
}). Uspjeh (funkcija (podaci) {
 $ range.data = podaci; 
}); 

Imajte na umu da ako koristite PHP, morat ćete upotrijebiti nešto poput Request::createFromGlobals() HTTP komponente Symfony 2, da biste je pročitali, jer se $ _POST neće automatski učitati s njom.

3
Aditya M P

Samo postavite Content-Type nije dovoljan, url kodira podatke podataka prije slanja. $http.post(url, jQuery.param(data))

3
Merlin Ran

Kompletan odgovor (od kutne 1.4). Morate uključiti ovisnost $ httpParamSerializer

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) { 

            });
2
Sebastián Rojas

AngularJS to radi ispravno kao što to čini sljedeće vrste sadržaja unutar zaglavlja http-zahtjeva:

Content-Type: application/json

Ako idete s php-om poput mene ili čak sa Symfony2, jednostavno možete proširiti kompatibilnost vašeg servera za json standard kao što je ovdje opisano: http://silex.sensiolabs.org/doc/cookbook/json_request_body.html

Na Symfony2 način (npr. Unutar vašeg DefaultController):

$request = $this->getRequest();
if (0 === strpos($request->headers->get('Content-Type'), 'application/json')) {
    $data = json_decode($request->getContent(), true);
    $request->request->replace(is_array($data) ? $data : array());
}
var_dump($request->request->all());

Prednost bi bila u tome što ne morate koristiti jQuery param i mogli biste koristiti AngularJS svoj izvorni način ispunjavanja takvih zahtjeva.

2
Michael

U vašoj konfiguraciji aplikacije -

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

Uz vaš zahtjev za resursom -

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

To nije izravan odgovor, već pomalo drugačiji smjer dizajna:

Ne objavljujte podatke u obliku, već kao JSON objekt za izravno preslikavanje u objekt sa strane poslužitelja ili upotrijebite REST varijablu staze stila

Sada znam da ni jedna opcija ne može biti prikladna u vašem slučaju jer pokušavate proslijediti XSRF ključ. Mapiranje u varijablu puta poput ove je grozan dizajn:

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

Jer po prirodi želite da xsrf ključ prebacite i na drugi put, /login, /book-appointment itd., A ne želite zabrljati lijepi URL

Zanimljivo je da ga dodavanje kao objektno polje nije prikladno ni zato što sada na svaki od json objekata koji pređete na poslužitelj morate dodati polje

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

Svakako ne želite dodati još jedno polje na vašu klasu na strani poslužitelja koje nema izravnu semantičku povezanost s objektom domene.

Po mom mišljenju, najbolji način da proslijedite svoj xsrf ključ je putem HTTP zaglavlja. Mnoge knjižnice web okvira okvira poslužitelja xsrf to podržavaju. Na primjer, u Java Springu, možete ga proslijediti pomoću X-CSRF-TOKEN zaglavlja .

Kutna izvrsna sposobnost vezanja JS objekta na UI objekt znači da se možemo riješiti prakse postavljanja obrasca svi zajedno i umjesto toga objaviti JSON. JSON se može lako deserializirati u objekt na strani poslužitelja i podržavati složene strukture podataka kao što su karta, nizovi, ugniježđeni objekti itd.

Kako objaviti niz u korisnom teretu obrasca? Možda ovako:

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

ili ovo:

shopLocation=downtwon&daysOpen=Monday,Tuesday,Wednesday

Oboje su lošeg dizajna.

0
gerrytan

Ovo radim za svoje potrebe, gdje trebam poslati podatke za prijavu u API kao podatke obrasca, a Javascript objekt (userData) automatski se pretvara u podatke kodirane URL-om.

        var deferred = $q.defer();
        $http({
            method: 'POST',
            url: apiserver + '/authenticate',
            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: userData
        }).success(function (response) {
            //logics
            deferred.resolve(response);
        }).error(function (err, status) {
           deferred.reject(err);
        });

Ovako je moj Korisnički podatak

var userData = {
                grant_type: 'password',
                username: loginData.userName,
                password: loginData.password
            }
0
Shubham