-
Notifications
You must be signed in to change notification settings - Fork 27.4k
AngularJS has different request data format from Jquery when send almost same post call #6039
Comments
You're asking for x-www-form-urlencoded, and angular doesn't encode data that way currently. I suppose we could, but I'm not sure I expect that to happen. I think for the time being you should just use jQuery when you need to send requests like this, and maybe if you want to implement this feature we could look at getting it into the tree. I'll mark this as PRz welcome. |
Related to #1743. I agree with @caitp that we could easily make people's life a bit easier. I guess we could try to do is:
|
Would it make sense for this functionality to live in a stand-alone module outside of core? Having it outside of core would make it easy to extend it and support other formats in the same way. I put together a proof of concept, and a Plunker demo. If this seems like the right direction, I'd be happy to continue development on it. |
+1 |
From personal observation, all I need to do to get this working is to wrap the Ex.
I feel it would just make life easier if AngularJS could provide an equivalent function to jQuery's |
+1. Coming here from the thread at #1743, I agree that this is a feature that is missing from Angular. My team was actually quite surprised to find that there were hoops to jump through to make a regular form post. In our case we have jQuery as a dependency, so we can use that until Angular has a "native" solution. |
Facing the same issue as well. Recently started working on a HTML5 app (Cordova) which calls a PHP backend for HTTP requests. The PHP backend is powering a number of different projects so even simple calls like login and authentication expect I've really liked the bits of AngularJS I've used but this came off as a very odd omission. Even if url-encoding isn't the standard when posting data, it is the convention expected by an overwhelming number of backend services, and Angular should support it out of the box. |
lets enumerate those services, particularly the ones where this is the only possible solution and it's simply impossible to do anything else after we've done that and established how big of a problem this is, because most people don't seem to run into this issue. |
There's almost always a workaround to things. I don't think you'll get a service where it's literally impossible to send forms with the current Angular implementation. As I mentioned in my post, in the end, I only needed jQuery's However, it did take me an extremely long time before I managed to realise the reason why my forms weren't sending and to find this workaround I'm currently using. It would be great if Angular could provide an internal function similar to |
A workaround for everything indeed, I never opened an issue because I assumed $.param was the defacto solution. A native implementation would be great. |
I have the exact same problem, php server does not accept OPTION method natively so I guess the problem is quite big. I have used $http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded"; to switch requests to application/x-www-form-urlencoded to get the request through. Unfortunately I do not have jQuery as a dependancy so $.param is not an option for me...are there any other workarounds? |
There must already be a function for this in angular, as it does it for 'params' key passed to $http... but it is not publicly accessible. I think this should change and be made public, and the default transformRequest should be changed too to serialize forms according the content-type header. For now though, if you do not want to reimplement the wheel over and over (even if its just 5 lines, I do agree it is bad news having to write it yourself), a clever trick I saw recently was to pass FormData object as data, no-op transformRequest so it doesn't get stringified as [object FormData] (offtopic, html5 spec wtf, why no adequate toString?), and undefined as content-type header so XHR.send will set correct multipart headers. For older browsers, there are FormData polyfills. Note the request becomes multipart instead of urlencoded though, often that is ok but for some backends it may still not cut it. |
+1 I too am facing the same issue. Hope this can be resolved from Angular itself? |
+1 |
Same here.. I don't want to add jQuery as a dependency just for this |
Unbelievable, AngularJS is so awesome that I cannot believe this so simple thing is missing. So everyone is using jQuery only for this serialization function? |
+1 It's pretty crazy such an advanced framework doesn't have this by default |
+1 jQuery should not be required to fix this, pretty basic functionality, form submission... |
This should really be prioritized for addition into the next version |
yes, lot of apis expect 'jquery' way so this functionality is required |
+1 for angular to incorporate this |
+1 |
For those trying to find a better solution: |
👍 |
Thanks @rodrigograca31. This sucks. Come on guys, people are spending hours on this. I bet most just go and add JQuery which is ridiculous, and in my case impossible... |
Just a heads up, this solution works great if you only need this to talk to Spring Security or something with simple requests |
@Narretz My previous response was directed specifically at @awebdeveloper and his code regarding older versions, sorry I didn't make it clear and may have left the impression I am criticizing angular's current version or something. But to answer you anyway, I haven't used 1.4 but from looking at the code it seems ok. Basically exactly what I wanted in my first post on the issue - expose the functionality used by $http "params" config option to be more generally accessible. Now users can call it for their data. Additional features like the default request transformer using that serializer for the request data based on the content-type header as proposed by others in this thread probably still fall under this issue. [And regarding the paramSerializers specifically - a missing "JQLike" feature of the "JQLike" serializer is the ability to handle array of {name, value} objects, to support same key appearing multiple times in the data, i.e. for cases like |
/cc @Narretz
|
@armanforghani I can't test right now, but this should work. Can you set up a plnkr that shows the problem? |
@armanforghani, the paramSerializers are for serializing URL query params, not the payload/data of the request. |
How can i serialize data for post request? Currently i use this way. Can you recommend better option? |
I can' really recommend a better option, because I never need to serialize the payload ala jQuery. |
@armanforghani There's also an example in the docs: https://docs.angularjs.org/api/ng/service/$httpParamSerializerJQLike Let me know if that doesn'T work |
It should be possible to have this behavior by default for all post requests, you would need to do // Warning, untested code
module.run(function($http, $httpParamSerializerJQLike) {
$http.defaults.transformRequest.unshift($httpParamSerializerJQLike);
}); |
@armanforghani please share if this actually worked, so other people can use the same mechanism if this is the behavior they are looking for |
I just tested it and it works perfectly. @lgalfaso Thank you so much. |
Given that there is a mechanism to achieve the desired behavior, then it should be safe to close this issue. If there is a spacial interest to make http request body data serialization configurable in an easier way, then open an issue linking this discussion. |
@lgalfaso I really disagree that this solves the problem. There is only a small subset of POST requests for which this is the right serializer so adding it for all requests isn't a good solution for the general case. The framework should be changed to use this serializer any time 'application/x-www-form-urlencoded' is the data type. Otherwise the framework is submitting bad data |
@AdamMcCormick I think it is perfectly fine to keep on with the discussion on data serialization for POST requests. This includes what should be configurable, and if this configuration should be part of the core or a third-party module. The way data is serialized is configurable as shown before, how this is done is documented https://docs.angularjs.org/api/ng/service/$http#transforming-requests-and-responses and there are some tools for different serialization mechanisms. Changing the default behavior would be a breaking change and something that we try to avoid. This is why there are several configuration points that, hopefully, will help developers make things work the way they need with minimal code. With all this information, it is not clear to me what should be changed. Can you please provide an example of something that is not possible, or that would need a substantial number of LOC to achieve? |
@pkozlowski-opensource you had a plan for this, right? Maybe you can outline what you would have done, and me or someone else can take a shot at it? |
@lgalfaso when I say I want "application/x-www-form-urlencoded" data (by telling angular the content type) it shouldn't be sending JSON at all! It should be sending the data object I provide as if it's a WWW Form (as the spec clearly outlines), like I tell it to. I'm not sure why that's so hard to understand. The current behavior is not spec compliant and thus wrong, so breaking change or not, it should change. It's not about what I think, and it doesn't matter if there's a workaround. @pkozlowski-opensource has stated several times how a solution could be implemented, and I am saying it should be. |
@AdamMcCormick, would it be possible to know what standard are you talking about? |
@lgalfaso you linked the spec for "application/x-www-form-urlencoded" above and it's pretty explicit as to how key/value pairs should be serialized and sent. When the content type is "application/x-www-form-urlencoded" the whole point is to emulate the way an HTML form would look if you had POST'd it. It's not a "body" it's a URL-encoded WWW form, it needs to act like it. |
@AdamMcCormick the spec at http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1 only applies to |
@lgalfaso It's NOT A JSON OBJECT. It's a JavaScript object that I am trying to use to replace a FORM. "application/x-www-form-urlencoded" is the data format, not "application/json." You are conflating the two and that's why you don't seem to be hearing me. http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1 specifies what ANY data transmitted with a content type of "application/x-www-form-urlencoded" MUST adhere to. That's "a compelling reason to justify a breaking change." What's more compelling than the current mode of operation being explicitly wrong? |
TL, DR:
JSON is the serialization, no need to serialize it again. 😁 application/x-www-form-urlencoded is another serialization specified as part of the HTML specs. The parameter Why does this look like a bug? To add, the documentation also do not state that $http will ignore "Content-type" and any other parameter header to decide which serialization method it will use. This is one use-case leading people to this github issue When this fails, you will think you or the framework did something wrong and will read the docs again, ask around, search the web, ... Somewhere near this point, you will learn about |
@ribeirobreno I agree completely. This has been my issue when working with angular 1 and after going throught exactly these steps and having to use $.param because I did not find out about $httpParamSerializer . After all this I came to the same problem with Angular 2 and now, again, my day is flying by while I'm trying to figure out how to do this without using jquery again since I have not been able to find $httpParamSerializer . What I'm interested even more is what backend framework are angular guys using not to come to this problem immediately since I've encountered this with both Flask and ASP.Net and on both the guys doing backend said it was my problem |
@DominikDitoIvosevic i've looked into the docs today and found this: https://docs.angularjs.org/api/ng/service/$http#default-transformations Don't know if i missed it before or if it was added... either way i think it would be really nice to have a reference to the "default transformations" next to the data parameters, here: https://docs.angularjs.org/api/ng/service/$http#usage |
I realize I'm coming at this very (very) late, but as someone new to Angular, I'm amazed that it's so awkward to get a This is one of several closed issues I've found on this topic. I won't comment on all of them, but I hope that enough voices will bring some visibility to the issue and make this quirk of Angular easier to use. |
As a newbie to Angular ! It helped me in 2017 :) |
i faced to this problem in angular2 |
I was tried to use AngularJS $http and coffeescript to send a cross domain post request. I've already changed the server side to make it available for cross domain request.
The question is when I was using Angular js to send request I found the request data is different from the request sent by jQuery.
Angular
then I got

Jquery
Then it works well, this request data format is what I want.

I don't know whether it's an issue, hope someone can help me out.
There is same question I posted on stackoverflow: http://stackoverflow.com/questions/21400743/angularjs-cant-send-post-request-with-content-typeapplication-json
The text was updated successfully, but these errors were encountered: