How do you send x-www-form-urlencoded data with Angular $resource?

帅比萌擦擦* 提交于 2019-12-10 04:41:01

问题


I am trying to submit a POST request to a server which only accepts the data in the x-www-form-urlencoded format.

When I test it out on Postman, it works. For example, the preview header looks like:

    POST /api/signin HTTP/1.1
    Host: myproj.herokuapp.com
    Cache-Control: no-cache
    Content-Type: application/x-www-form-urlencoded

    email=joe%40gmail.com&password=1234567

However, when I run it from my app, the header, as viewed in Chrome console, looks like:

    Remote Address:10.10.10.250:80
    Request URL:http://myproj.herokuapp.com/api/signIn
    Request Method:POST
    Status Code:400 Bad Request
    Request Headersview source
    Accept:application/json, text/plain, */*
    Accept-Encoding:gzip, deflate
    Accept-Language:en-US,en;q=0.8
    Connection:keep-alive
    Content-Length:53
    Content-Type:application/x-www-form-urlencoded; charset=UTF-8
    Host:rapidit.herokuapp.com
    Origin:http://localhost
    Referer:http://localhost/rapid/v3/src/app/index/
    User-Agent:Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36
    Form Dataview parsed
    {"email":"joe@gmail.com","password":"1234567"}

Clearly, it's not sending the data in the right format.

This is what it looks like in my Angular factory (with hardcoded login data):

var LoginResource = $resource("http://myproj.herokuapp.com/api/signIn", {}, {
         post: {
            method: "POST",
            isArray: false,
            headers: {'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'}
        }
    });
    var loginUser = function (){
        return LoginResource.post( 
            {
                email: "joe@gmail.com", 
                password: "1234567" 
            }
            ).$promise; //this promise will be fulfilled when the response is retrieved for this call
    };
    return loginUser;

How can I get the data to POST in the required format?


回答1:


By default Angular uses application/json and it's not enough to set the header to form url encode, you have to actually transform the data, you can do that by using de transformRequest option on the $resource service. This is how it looks like.

angular.module("AuthModule")
.factory("authResource", ['$resource', 'appSettings', function ($resource, appSettings) {

    return {
        login: $resource(appSettings.serverPath + '/Token', null,
           {
               loginUser: {
                   method: 'POST',
                   headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                   transformRequest: function (data, headersGetter) {
                       var str = [];
                       for (var d in data)
                           str.push(encodeURIComponent(d) + "=" + encodeURIComponent(data[d]));
                       return str.join("&");
                   }
               },
           })
    }

}]);

P/D: I didn't write this. This code was taken from a pluralsight's course, called Angular Front to Back with Web API.




回答2:


Since angularjs 1.4, you can use $httpParamSerializer:

function transformUrlEncoded(data) {
    return $httpParamSerializer(parameters); 
}

...

$resource('http://myproj.herokuapp.com/api/signIn', {}, {
    post: {
        method: "POST",
        headers: {'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'},
        transformRequest: transformUrlEncoded
    }
});



回答3:


I had a similar problem, AngularJS $resource service posts the data in JSON format by default, i.e. if you check the Content-type header in the request you'll see Content-type: application/json.

In my case my server can handle those payloads, but found a Google thread that might help in your case.




回答4:


This is very nice way of communication with Symfony forms for AngularJS:

Thanks for s1moner3d for hint

class AngularForm
{
constructor($scope, $http, $httpParamSerializerJQLike) {
    'ngInject';
    this.http = $http;
    this.input= '';
    this.$httpParamSerializerJQLike = $httpParamSerializerJQLike;
}

sendForm(){

    let conf = {
        method: 'POST',
        headers: {'Content-Type': 'application/x-www-form-urlencoded'},
        url: '/api/input',
        data: this.$httpParamSerializerJQLike({'name_of_form': {'input':this.input}}),
    }

    this.http(conf).then( (response)=>{
        //success
    }, (response)=> {
        //error :(
    });

}

}


来源:https://stackoverflow.com/questions/27375710/how-do-you-send-x-www-form-urlencoded-data-with-angular-resource

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!