Jak mogę zamieścić dane w formularzu zamiast żądania?

W poniższym kodzie metoda AngularJS $http wywołuje adres URL i przesyła obiekt xsrf jako "Request Payload" (jak opisano w zakładce Sieć debugerów Chrome). Metoda jQuery $.ajax wykonuje to samo wywołanie, ale przesyła xsrf jako "dane formularza".

Jak mogę zmusić AngularJS do przesłania xsrf jako danych formularza zamiast żądania ładunku?

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() {}
});
Author: Damjan Pavlica, 2012-07-12

22 answers

Do przekazywanego obiektu $http należy dodać następującą linię:

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

I przekazane dane powinny być przekonwertowane na łańcuch zakodowany URL:

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

Więc masz coś w stylu:

$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

UPDATE

Aby korzystać z nowych usług dodanych w AngularJS V1. 4, Zobacz

 594
Author: mjibson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-29 06:50:09

Jeśli nie chcesz używać jQuery w rozwiązaniu, możesz spróbować tego. Rozwiązanie nabyte stąd 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
Author: Anthony,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:55:01

Ciągłe zamieszanie wokół tej kwestii zainspirowało mnie do napisania posta na blogu. Rozwiązanie, które proponuję w tym poście jest lepsze od Twojego obecnego najlepiej ocenianego rozwiązania, ponieważ nie ogranicza cię do parametryzacji obiektu danych dla wywołań usługi $ http; tzn. z moim rozwiązaniem możesz po prostu kontynuować przekazywanie rzeczywistych obiektów danych do $http.post () itp. i nadal osiągnąć pożądany rezultat.

Również najlepiej oceniana odpowiedź polega na dodaniu pełnego jQuery na stronie dla $.funkcja param (), natomiast moim rozwiązaniem jest jQuery, pure AngularJS ready.

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

Mam nadzieję, że to pomoże.

 91
Author: Ezekiel Victor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-21 12:07:16

Wzięłam kilka innych odpowiedzi i zrobiłam coś czystszego, umieściłam to wezwanie na końcu twojego kąta.moduł w Twojej aplikacji.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
Author: kzar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-14 08:52:14

Począwszy od AngularJS v1. 4. 0, istnieje wbudowana usługa $httpParamSerializer, która konwertuje dowolny obiekt na Część żądania HTTP zgodnie z regułami wymienionymi na stronie docs.

Można go używać w następujący sposób:

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

Pamiętaj, że dla poprawnego postu formularza, nagłówek Content-Type musi zostać zmieniony. Aby to zrobić globalnie dla wszystkich żądań Posta, można użyć tego kodu (zaczerpniętego z połowy odpowiedzi Albireo):

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

Aby to zrobić tylko dla bieżącego posta, headers własność request-object needs to be modified:

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

$http(req);
 57
Author: Mitja,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-01 19:57:20

Możesz zdefiniować zachowanie globalnie:

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

Więc nie musisz go redefiniować za każdym razem:

$http.post("/handle/post", {
    foo: "FOO",
    bar: "BAR"
}).success(function (data, status, headers, config) {
    // TODO
}).error(function (data, status, headers, config) {
    // TODO
});
 24
Author: Albireo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-02 15:25:52

Jako obejście możesz po prostu sprawić, aby Kod otrzymujący POST odpowiadał na dane aplikacji / json. Dla PHP dodałem poniższy kod, pozwalając mi pisać do niego w formie zakodowanej lub 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
Author: James Bell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-08 22:57:52

Te odpowiedzi wyglądają jak szalone przesady, czasami proste jest po prostu lepsze:

$http.post(loginUrl, "userName=" + encodeURIComponent(email) +
                     "&password=" + encodeURIComponent(password) +
                     "&grant_type=password"
).success(function (data) {
//...
 16
Author: Serj Sagan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-24 09:19:28

Możesz spróbować z poniższym rozwiązaniem

$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
Author: tmquang6805,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-09 11:00:31

Utwórz usługę adaptera dla posta:

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

}) 

Użyj go w kontrolerach lub w ogóle:

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
Author: Ozgur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-16 23:41:34

Jest naprawdę fajny samouczek, który omawia to i inne powiązane rzeczy- przesyłanie formularzy AJAX: sposób AngularJS .

Zasadniczo musisz ustawić nagłówek żądania POST, aby wskazać, że wysyłasz dane formularza jako łańcuch zakodowany URL, i ustawić dane, które mają być wysłane w tym samym formacie

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

Zauważ, że pomocnicza funkcja jQuery param() jest tutaj używana do serializacji danych w łańcuchu znaków, ale możesz to zrobić również ręcznie, jeśli nie używasz jQuery.

 7
Author: robinmitra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-02 12:33:34
var fd = new FormData();
    fd.append('file', file);
    $http.post(uploadUrl, fd, {
        transformRequest: angular.identity,
        headers: {'Content-Type': undefined}
    })
    .success(function(){
    })
    .error(function(){
    });

Proszę Do kasy! https://uncorkedstudios.com/blog/multipartformdata-file-upload-with-angularjs

 6
Author: aul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-29 10:14:13

Dla użytkowników Symfony2:

Jeśli nie chcesz niczego zmieniać w swoim javascript, aby to działało, możesz wykonać te modyfikacje w aplikacji symfony:

Utwórz klasę rozszerzającą klasę Symfony \ Component\HttpFoundation\Request:

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

}

}

Teraz używaj klasy w app_dev.php (lub dowolny plik indeksu, którego używasz)

// 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
Author: carmel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-05 09:37:54

Wystarczy ustawić Content-Type to za mało, url zakoduje dane formularza przed wysłaniem. $http.post(url, jQuery.param(data))

 3
Author: Merlin Ran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-01 09:12:19

Obecnie używam następującego rozwiązania, które znalazłem w grupie Google AngularJS.

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

Zauważ, że jeśli używasz PHP, musisz użyć czegoś takiego jak komponent http Symfony 2 Request::createFromGlobals(), aby to odczytać, ponieważ $_POST nie zostanie automatycznie załadowany.

 3
Author: Aditya M P,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-15 23:02:22

AngularJS robi to dobrze, ponieważ wykonuje następujący typ treści wewnątrz nagłówka HTTP-request:

Content-Type: application/json

Jeśli korzystasz z php jak ja, lub nawet z Symfony2 możesz po prostu rozszerzyć kompatybilność serwera dla standardu json, jak opisano tutaj: http://silex.sensiolabs.org/doc/cookbook/json_request_body.html

Sposób Symfony2 (np. wewnątrz Twojego Defaultcontrollera):

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

Zaletą byłoby to, że nie trzeba używać jQuery param i możesz użyć AngularJS jego natywny sposób robienia takich żądań.

 2
Author: Michael,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-22 10:27:08

Pełna odpowiedź (od angular 1.4). Musisz dołączyć de dependency $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
Author: Sebastián Rojas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-20 21:46:28

W konfiguracji aplikacji -

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

Z żądaniem zasobów -

 headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            }
 1
Author: Vivek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-14 17:46:43

To nie jest bezpośrednia odpowiedź, ale raczej nieco inny kierunek projektowania:

Nie publikuj danych jako formularza, ale jako obiekt JSON, który ma być bezpośrednio odwzorowany na obiekt po stronie serwera lub użyj zmiennej ścieżki stylu REST

Teraz wiem, że żadna opcja nie może być odpowiednia w Twoim przypadku, ponieważ próbujesz przekazać klucz XSRF. Mapowanie go do zmiennej path takiej jak ta jest fatalnym projektem:

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

Ponieważ z natury chciałbyś przekazać klucz xsrf również innej ścieżce, /login, /book-appointment itd. i nie chcesz zepsuć swojego pięknego adresu URL

Co ciekawe, dodanie go jako pola object również nie jest odpowiednie, ponieważ teraz na każdym obiekcie JSON, który PRZEKAZUJESZ do serwera, musisz dodać pole

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

Z pewnością nie chcesz dodawać kolejnego pola na swojej klasie po stronie serwera, które nie ma bezpośredniego związku semantycznego z obiektem domain.

Moim zdaniem najlepszym sposobem na przekazanie klucza xsrf jest nagłówek HTTP. Wiele ochrony xsrf serwerowa biblioteka web Framework obsługuje to. na przykład w Java Spring można go przekazać używając X-CSRF-TOKEN nagłówka.

Doskonała zdolność Angular do wiązania obiektu JS z obiektem UI oznacza, że możemy pozbyć się praktyki wysyłania formularza razem, a zamiast tego post JSON. JSON może być łatwo zdeserializowany do obiektu po stronie serwera i obsługuje złożone struktury danych, takie jak mapy, tablice, zagnieżdżone obiekty itp.

Jak wstawić tablicę w formularzu? Może jak to:

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

Lub to:

shopLocation=downtwon&daysOpen=Monday,Tuesday,Wednesday

Oba są kiepskim projektem..

 0
Author: gerrytan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-26 11:47:42

To jest to, co robię dla mojej potrzeby, gdzie muszę wysłać dane logowania do API jako dane formularza i obiekt Javascript (userData) jest automatycznie konwertowany do danych zakodowanych URL

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

Tak wygląda moje Userdata

var userData = {
                grant_type: 'password',
                username: loginData.userName,
                password: loginData.password
            }
 0
Author: Shubham,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-25 07:56:42

Jedyne, co musisz zmienić, to użyć właściwości "params" zamiast "data" podczas tworzenia obiektu $http:

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

W powyższym przykładzie klient [i] jest tylko obiektem JSON (nie serializowanym w żaden sposób). Jeśli użyjesz "params" zamiast "data", kątowy będzie serializował obiekt za pomocą $httpParamSerializer: https://docs.angularjs.org/api/ng/service/$httpParamSerializer

 -1
Author: Rafal Zajac,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-13 16:05:17

Użyj usługi AngularJS $http i użyj jej metody post lub skonfiguruj funkcję $http.

 -3
Author: Shivang Gupta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-30 09:28:41