How can I post data as form data instead of a request payload?

前端 未结 22 2212
庸人自扰
庸人自扰 2020-11-22 00:13

In the code below, the AngularJS $http method calls the URL, and submits the xsrf object as a \"Request Payload\" (as described in the Chrome debugger network t

相关标签:
22条回答
  • 2020-11-22 00:32

    There is a really nice tutorial that goes over this and other related stuff - Submitting AJAX Forms: The AngularJS Way.

    Basically, you need to set the header of the POST request to indicate that you are sending form data as a URL encoded string, and set the data to be sent the same format

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

    Note that jQuery's param() helper function is used here for serialising the data into a string, but you can do this manually as well if not using jQuery.

    0 讨论(0)
  • 2020-11-22 00:35

    If you do not want to use jQuery in the solution you could try this. Solution nabbed from here 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 () {});
    
    0 讨论(0)
  • 2020-11-22 00:35

    Create an adapter service for 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'}
            })
        }
    
    }) 
    

    Use it in your controllers or whatever:

    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)
            })
        }
    
    })
    
    0 讨论(0)
  • 2020-11-22 00:35
    var fd = new FormData();
        fd.append('file', file);
        $http.post(uploadUrl, fd, {
            transformRequest: angular.identity,
            headers: {'Content-Type': undefined}
        })
        .success(function(){
        })
        .error(function(){
        });
    

    Please checkout! https://uncorkedstudios.com/blog/multipartformdata-file-upload-with-angularjs

    0 讨论(0)
  • 2020-11-22 00:35

    This isn't a direct answer, but rather a slightly different design direction:

    Do not post the data as a form, but as a JSON object to be directly mapped to server-side object, or use REST style path variable

    Now I know neither option might be suitable in your case since you're trying to pass a XSRF key. Mapping it into a path variable like this is a terrible design:

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

    Because by nature you would want to pass xsrf key to other path too, /login, /book-appointment etc. and you don't want to mess your pretty URL

    Interestingly adding it as an object field isn't appropriate either, because now on each of json object you pass to server you have to add the field

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

    You certainly don't want to add another field on your server-side class which does not have a direct semantic association with the domain object.

    In my opinion the best way to pass your xsrf key is via a HTTP header. Many xsrf protection server-side web framework library support this. For example in Java Spring, you can pass it using X-CSRF-TOKEN header.

    Angular's excellent capability of binding JS object to UI object means we can get rid of the practice of posting form all together, and post JSON instead. JSON can be easily de-serialized into server-side object and support complex data structures such as map, arrays, nested objects, etc.

    How do you post array in a form payload? Maybe like this:

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

    or this:

    shopLocation=downtwon&daysOpen=Monday,Tuesday,Wednesday
    

    Both are poor design..

    0 讨论(0)
  • 2020-11-22 00:36

    AngularJS is doing it right as it doing the following content-type inside the http-request header:

    Content-Type: application/json
    

    If you are going with php like me, or even with Symfony2 you can simply extend your server compatibility for the json standard like described here: http://silex.sensiolabs.org/doc/cookbook/json_request_body.html

    The Symfony2 way (e.g. inside your 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());
    

    The advantage would be, that you dont need to use jQuery param and you could use AngularJS its native way of doing such requests.

    0 讨论(0)
提交回复
热议问题