-
Notifications
You must be signed in to change notification settings - Fork 27.4k
$http is parsing a request to JSON ignoring the content-type #15897
Comments
Originally, AngularJS ignored the content type header completely and always tried to parse JSON: 7b6c1d0 This was changed to additionally always parse when the content-type header is set, and after that, only the json-likeness detection was updated. Changing this would possibly break a lot of apps that simply don't set their content-type headers on the server correctly. If you know that your response will always return text, you can detect this and skip the default transform, e.g. like this http://plnkr.co/edit/DgNEA1s62brfhVgsv6OL Or, if your API always returns text, remove the default http transform. Note that the error you linked to is valid only from 1.6.4 onwards - before that you get a generic JSOn parse error. But you are right that the error description is not correct about the workaround, because setting the header doesn't fix it. |
We could also employ some advanced heuristics to detect that this is not json, but this basically means we would have to parse the JSON. Pinging @gkalpak since he last worked on this code. |
- baddata error described incorrect http behavior, and workarounds - httpProvider defaults were missing transformResponse / transformRequest - http was not clear about JSON detection strategy Closes angular#15897
Question: The responseType option shouldn't define the expected content-type? And if that option doesn't do it, we can't add an option to set the expected content-type and don't try to parse to json? Because even if we improve it with advanced heuristics, if we send a json object as text, or something that still appears to be a json we will have the same problem. |
Yes, this is the current status quo. Text that looks like json according to our detection will be parsed as such. We could add an option, but I don't know many devs would benefit from this, especially since there are workarounds. |
At this point, I agree it is probably not worth addressing other than documenting the current behavior and work-around (as it could be a significant breaking change) 👍 |
Hi folks, I found this thread through Google and was not expecting the conclusion:
I think I'm seeing the same issue as described above but don't know how to get The HTTP call returns Please could you point me at the docs or workaround that I can use to prevent angular / The plain-text value is: The code driving the page is here: https://github.com/openfaas/faas/blob/master/gateway/assets/script/bootstrap.js#L93 Thanks in advance for your help. |
@alexellis - The workaround depends upon your situation. See #15897 (comment) The heavy-handed approach (which especially works if you never get JSON from $http requests) is to remove the default transform from the Otherwise you could remove the default transform on a request by request basis. Or finally you could replace the default transform with a more complex one that is able to work out whether your request expected JSON or not. |
Thanks for a quick response @petebacondarwin. The UI for OpenFaaS can invoke functions via a web form - it looks similar to Postman. So you will see a request body entered and can indicate its format and after invoking will see the response in the bottom part of the screen. I believe we should largely be able to detect the content through the Content-Type sent back from the server. I looked at the plunker example but I don't see how the function Example: |
Yes, that Plunker is not very helpful :-/ Here is the relevant section in the docs: https://docs.angularjs.org/api/ng/service/$http#transforming-requests-and-responses The general idea would be to override the transform in your request: $http({
url: '...',
method: 'GET',
transformResponse: myTranformFn
}); where function myTransformFn(data, headersGetter, status) {
if (isJsonType(headersGetter()['Content-Type']) {
return JSON.parse(data);
} else {
return data;
}
} |
I believe we changed this behavior here: 7f2acca#diff-748e0a1e1a7db3458d5f95d59d7e16c9 so that http will only throw if the content type is set to json, but can't be parsed. This is available in 1.6.6. Open Faas uses AngularJS 1.5.5. So this could be fixed by updating AngularJS |
Uh oh!
There was an error while loading. Please reload this page.
I'm submitting a ...
Current behavior:
The transformResponse is being executed based on a text/plain content, instead of the content-type headers, causing errors sometimes.
Expected / new behavior:
The transformResponse has to be called based on the content-type headers.
Minimal reproduction of the problem with instructions:
$http.get is trying parse to json a text/plain response (the content-type header from the server is "text/plain") when the text starts with "[" and ends with "]" characters.
Looking the documentation for baddata it says that it parses the body when the content-type header is application/json, and "the response looks like a valid JSON-stringified object or array".
And when I change the default transformResponse function to:
$http.get('/', { transformResponse: [function (data) { return data; }] })
To do nothing when it's called, the request works.
The $http request ignores the content-type response header and try to parse my response based in the body of the response?
Angular version: 1.6.2
Browser: all
Anything else:
I'm not sure how it detects that the body "looks like" a json to parse it automatically. But if the content-type of the response is "text/plain" it doesn't have to parse it, even if the body is a json object (not my case).
The text was updated successfully, but these errors were encountered: