Binary body of a request gets corrupted in the handler
See original GitHub issueEnvironment
Name | Version |
---|---|
msw | 0.35.0 |
browser | Microsoft Edge |
OS | Windows 10 |
Request handlers
Mocking setup via storybook add-on:
import { rest } from "msw";
component.parameters = {
msw: [
rest.post(
"/api/xyz/42",
( req,res, ctx ) => { ... }]];
In the req.body I expect a multipart content which owns an jpeg image.
In preview.js I have:
import { initializeWorker, mswDecorator } from "msw-storybook-addon";
initializeWorker();
addDecorator(mswDecorator);
Actual request
The request is a multipart content which contains a jpeg image sent by fetch.
Current behavior
The data received in the request handler is a damaged jpeg file. After a lot debugging I found out that the image data gets damaged at two locations:
- In mockServiceWorker.js function getResponse. There the body of the request is extracted by using request.text(). This damages the binary data because the data is converted to utf-8.
The request body is always decoded using UTF-8
- In RequestHandler.ts function parseMultipartData there is a call to the constructor of File with
This fails because the content body given to the File constructor is encoded as UTF-8 but here the data have to be given as an ArrayBuffer.
Expected behavior
Expected is that the data from the post request will not get damaged. To prevent a damage of the image for 1. the content should be get as unicode string by using something like this:
const body = String.fromCharCode(...new Uint8Array(await request.arrayBuffer()))
For 2. we need transform the extracted data of the multipart data so the image correctly used for the creation of the File. To transform it back from unicode string to ArrayBuffer we need soething like this:
const encoded = Uint8Array.from([...contentBody].map(ch => ch.charCodeAt())).buffer;
const imageFile = new File(encoded, filename, { type: contentType });
Issue Analytics
- State:
- Created 2 years ago
- Reactions:4
- Comments:11 (3 by maintainers)
Top GitHub Comments
Hi PupoSDC,
have you tried to use the fromCharCode for single characters in a for loop like this:
let body = “”; const uint8Arr = new Uint8Array(await request.arrayBuffer()); for (let i = 0; i < uint8Arr.byteLength; i++) { body += String.fromCharCode(uint8Arr[i]) }
This is not an effective way but it should work.
Another way should be:
const body = new TextDecoder().decode(new Uint8Array(await request.arrayBuffer()));
Did it work with this?
Greetings Michael
Hi kettanaito,