Different behaviors of Body.arrayBuffer() between Nodejs and Browser
Closed this issue · 8 comments
Hi,
the arrayBuffer() method of the Body
class behaves differently depending on it is in nodejs or in browser version, even though both return an ArrayBuffer.
Let's suppose there is an endpoint that is expected to return an octet-stream media type, e.g., file stream result, memory stream (c#-like types, based on a byte array).
In the following, I report the issue/problem I encountered after calling the fetch
function that accepts an 'octet-stream':
While in nodejs the arrayBuffer()
method extracts from the rawBody (in common.js) a stream object, and the latter is properly converted into an ArrayBuffer by the node.js function streamToBuffer(stream)
(and I'd say correctly converted as it matches exactly with the content of the object that the endpoint returned), in the browser version something changes.
In fact, the "rawBody" object is an utf8 string conversion (with loss of information) of the object the endpoint returned. Then, the streamToArrayBuffer(rawBody)
in browser.js converts forcibly (I may be wrong saying that) the string rawBody into an array buffer. The content of the returned object (in this case) is totally wrong and does not match with the one the endpoint returned.
I kindly ask you either if the above problem can represent a bug/issue, or some hints on how to solve this problem.
In the image below you can see the value of the rawBody of the response in the browser version of the library. The byte array (c#-like stream type) is converted into a string.
Thanks in advance
Sergio A.
This is a tricky one and may require replacing XHR with fetch, which can probably be done nowadays since XHR was around to support old IE versions. I’ll take a look and see if there’s something I can do regardless, but this happens because with XHR you need to specify “type” before you get a response and we’re only getting strings today (streaming doesn’t currently work in the browser either). I expect to resolve this over the weekend since it’s a larger problem with using XHR and needs thought about older browsers.
Hi,
Honestly, I did not get what you mean by saying "replacing XHR with fetch".
Also, how can I specify the "type" with XHR before getting the response?
The last question is the following:
- what is the right encoding (from byte array to string) of the returned object?
Thanks in advance for your availability, I am looking forward to getting fixed this bug.
Cordiality
Sergio A.
I've released a new minor version that supports arraybuffer
natively (loses support for IE < 10), let me know if that works for you!
What I meant was only internal comments, sorry! For complete support of streaming and other features available in node.js, we'd need to switch to fetch
in browser environments (entirely transparent to you). The only downside is that there's no fetch
on IE, but that's likely a non-issue since there's other non-IE dependencies that popsicle
requires today.
Hi,
No, It still does not work.
Checking out your latest commits I noticed that only popsicle and popsicle-transport-xhr package.json have been modified.
Is it correct?
Yes.
Can you describe more about what doesn't work? I tested it on some trivial examples and it appeared to work. The log you did above should be enough to help me understand.
[SOLVED]
Hi,
I have been trying hard to grab the bug/issue that was leading to this unexpected behavior, and finally I got it!
I am so pleased to inform you that it now works smoothly.
The $rawBody
is correctly typed as an arrayBuffer
, when the expected return value of my endpoint is an octet-stream media type, as you can see in the following:
I am so regret to notify you that libraries for browser stream handling affected the expected behavior. So, it's their fault.
T.hanks for your helping and availability
Sergio
Perfect, thanks for the update! I'll close this out as resolved and look into fetch
in the browser for the next major version. You shouldn't see any difference, but one of the benefits of fetch
is that it can support streaming while XHR doesn't. For buffered use-cases the behavior would be identical.