-
Notifications
You must be signed in to change notification settings - Fork 27.4k
$http always transform response content '[abc}' to JSON even we already set resp content type as 'application/octet-stream' #10349
Comments
I've met with the same issue.
|
This is a valid issue. There are number of things that we could improve in 1.3 (ex. making sure that starting and ending chars are the same in JSON-like strings, doing JSON-like detection only for certain response headers etc.), but the "proper" fix would consist of doing JSON-deserialization only if @caitp @petebacondarwin what do you guys think of fixing it in 1.4? I still do afraid that it would break applications for people interacting with non-well-behaving backends but yeh, at least we would avoid issues like this one. |
I hope this can be solved elegantly in 1.4. |
The content-type header was supposed to be respected in all cases in 1.3 --- if we keep saying it's too big of a breaking change, it's never going to be properly respected. |
However, there is a solution: |
@caitp: Are you suggesting using |
Agree with @gkalpak , for HTML template using |
The only reason it's not a good idea is because you lose access to the rest of the $http API, but $templateRequest is just a thin wrapper around $http which removes the builtin JSON parsing transformer. (Well, it does some animation-specific other things, but these don't matter a whole lot). While caching may be undesirable, it's easily circumvented |
Looking at the code, I can't really see how it could be circumvented at all. (It seems to be hardcoded into the So, the only reasons I can think of (and I wasn't even aware of the animation-specific stuff):
Wouldn't it be a better idea to just remove the default transform ? |
By deleting it from the cache...
No, we have it for a good reason --- supported browsers don't all support responseType=json, and we wouldn't really know when to ask for responseType=json even if they did.
Anyone could write a similar thin wrapper around http, it's just an example --- realistically, it's not going to change, because it doesn't need to do anything special |
I didn't mean for us to remove the default transform. I meant for the user/developer (and not necessarily for all requests). |
Previously, due to weak JSON-detecting RegExp, string like `[...}` and `{...]` would be considered JSON (even if they obviously aren't) and an expection would be thrown while trying to parse them. This commit makes sure the opening and closing brackets match. This doesn't completely eliminate false positives (e.g. `[]{}[]`), but does help reduce them. Closes angular#10349
Previously, due to weak JSON-detecting RegExp, string like `[...}` and `{...]` would be considered JSON (even if they obviously aren't) and an expection would be thrown while trying to parse them. This commit makes sure the opening and closing brackets match. This doesn't completely eliminate false positives (e.g. `[]{}[]`), but does help reduce them. Closes angular#10349
Previously, due to weak JSON-detecting RegExp, string like `[...}` and `{...]` would be considered JSON (even if they obviously aren't) and an expection would be thrown while trying to parse them. This commit makes sure the opening and closing brackets match. This doesn't completely eliminate false positives (e.g. `[]{}[]`), but does help reduce them. Closes angular#10349
Using $templateCache is definitely not a valid workaround. It is not supposed to be used for this and as pointed out even adds wrinkles of its own. If you provide a transformResponse property on your $http request object then this will be used instead of the default. So your options are to provide a custom transform per request or replace See https://docs.angularjs.org/api/ng/service/$http#transforming-requests-and-responses |
Previously, due to weak JSON-detecting RegExp, string like `[...}` and `{...]` would be considered JSON (even if they obviously aren't) and an expection would be thrown while trying to parse them. This commit makes sure the opening and closing brackets match. This doesn't completely eliminate false positives (e.g. `[]{}[]`), but does help reduce them. Closes angular#10349
Previously, due to weak JSON-detecting RegExp, string like `[...}` and `{...]` would be considered JSON (even if they obviously aren't) and an expection would be thrown while trying to parse them. This commit makes sure the opening and closing brackets match. This doesn't completely eliminate false positives (e.g. `[]{}[]`), but does help reduce them. Closes angular#10349
It is a valid workaround --- it does not add any wrinkles --- If you were to use $templateRequest (which deals with removing the transform) in addition to removing the cached value on resolve, the only issues you're left with is not having the exact same API. The real best solution is just writing a thin wrapper service around $http native to your own app, but the point here is that you can use $templateRequest as a guide for doing this. This ain't rocket science folks, there are literally only two constraints here, and they're trivial to implement. |
Previously, due to weak JSON-detecting RegExp, string like `[...}` and `{...]` would be considered JSON (even if they obviously aren't) and an expection would be thrown while trying to parse them. This commit makes sure the opening and closing brackets match. This doesn't completely eliminate false positives (e.g. `[]{}[]`), but does help reduce them. Closes angular#10349
Previously, due to weak JSON-detecting RegExp, string like `[...}` and `{...]` would be considered JSON (even if they obviously aren't) and an expection would be thrown while trying to parse them. This commit makes sure the opening and closing brackets match. This doesn't completely eliminate false positives (e.g. `[]{}[]`), but does help reduce them. Closes angular#10349
Previously, due to weak JSON-detecting RegExp, string like `[...}` and `{...]` would be considered JSON (even if they obviously aren't) and an expection would be thrown while trying to parse them. This commit makes sure the opening and closing brackets match. This doesn't completely eliminate false positives (e.g. `[]{}[]`), but does help reduce them. Closes angular#10349
As title, we ran into this issue when we try to get blob content from azure, using
$http.get(url).then();
. Angular would throw exception "Syntax error: Invalid ...". Seems Angular always try to render our blob content as JSON. After reading code in /src/ng/http.js, I think I may know why.In this piece of code,
$http
will try to detect response's content. If thecontentType
is equal toapplication/json
, $http will transform the content to JSON object then return to users. It does make sense.But if the
contentType
is notapplication/json
, it would use(JSON_START.test(data) && JSON_END.test(data))
to identify whether the content is a JSON object. This is not accurate and not intuitive either. A string starts/ends with '[ { ] }' doesn't mean it's JSON, you can't even say it's like JSON.For example, when you are writing a markdown article, maye API document, you may write a piece of content like below:
Obviously, it's not JSON while
(JSON_START.test(data) && JSON_END.test(data)
will return true. This kind of RegEx is weak.BTW, if users set response content-type explicitly, like
application/octet-stream
orapplication/text-HTML
, it means yeah I know I am returning you a byte array or a piece of HTML. But AngularJS still try to transform it to JSON, and booom, throw an exception...For now I can only set the response type while making ajax calls:
$http.get(url, {responseType: byteArray})
. Can we remove this RegEx check and give users less bother like Jquery does?The text was updated successfully, but these errors were encountered: