diff --git a/.changeset/binarybody-transformed.md b/.changeset/binarybody-transformed.md new file mode 100644 index 000000000..599a93ae1 --- /dev/null +++ b/.changeset/binarybody-transformed.md @@ -0,0 +1,5 @@ +--- +"dropzone": patch +--- + +Fix `binaryBody` uploads sending the original file instead of the transformed one. `resizeWidth`, `resizeHeight` and any custom `transformFile` were silently ignored, so an unresized image went to the server. Chunked and form-data uploads were unaffected. diff --git a/packages/dropzone/src/dropzone.ts b/packages/dropzone/src/dropzone.ts index 89131f7ec..f14067dcf 100644 --- a/packages/dropzone/src/dropzone.ts +++ b/packages/dropzone/src/dropzone.ts @@ -1611,7 +1611,7 @@ export default class Dropzone extends Emitter { if (this.options.uploadMultiple) { this.emit("sendingmultiple", files, xhr); } - this.submitRequest(xhr, null as any, files); + this.submitRequest(xhr, null, files, dataBlocks); } else { let formData = new FormData(); @@ -1659,7 +1659,7 @@ export default class Dropzone extends Emitter { formData.append(dataBlock.name, dataBlock.data, dataBlock.filename); } - this.submitRequest(xhr, formData, files); + this.submitRequest(xhr, formData, files, dataBlocks); } } @@ -1839,7 +1839,12 @@ export default class Dropzone extends Emitter { ); } - submitRequest(xhr: XMLHttpRequest, formData: FormData, files: DropzoneFile[]) { + submitRequest( + xhr: XMLHttpRequest, + formData: FormData | null, + files: DropzoneFile[], + dataBlocks?: any[], + ) { if (xhr.readyState != 1) { console.warn("Cannot send this request because the XMLHttpRequest.readyState is not OPENED."); return; @@ -1849,7 +1854,12 @@ export default class Dropzone extends Emitter { const chunk = this._getChunk(files[0], xhr)!; xhr.send(chunk.dataBlock.data); } else { - xhr.send(files[0]); + // `files[0]` is the file as it was dropped, not what should go on the + // wire: `transformFile` may have replaced it, which is how + // `resizeWidth` and `resizeHeight` work. The result is in + // `dataBlocks`, the same as for the chunked and form-data paths. The + // fallback is for anyone calling this themselves without them. + xhr.send(dataBlocks ? dataBlocks[0].data : files[0]); } } else { xhr.send(formData); diff --git a/packages/dropzone/test/unit-tests/amazon-s3.js b/packages/dropzone/test/unit-tests/amazon-s3.js index 6fc296327..11f07c8cb 100644 --- a/packages/dropzone/test/unit-tests/amazon-s3.js +++ b/packages/dropzone/test/unit-tests/amazon-s3.js @@ -61,6 +61,29 @@ describe("Amazon S3 Support", function () { dropzone.destroy(); return xhr.restore(); }); + it("should send the file itself when there is nothing to transform", async () => { + let file = getMockFile("text/plain", "plain.txt", ["original contents"]); + dropzone.addFile(file); + await sleep(10); + + expect(requests[0].body).toBe(file); + }); + + // The point of binaryBody is uploading straight to a bucket, which is + // exactly where resizeWidth/resizeHeight are wanted -- and transformFile + // is how those work. The transformed blob was being dropped and the + // original file uploaded in its place. + it("should send what transformFile produced, not the original file", async () => { + let transformed = new Blob(["transformed contents"], { type: "text/plain" }); + dropzone.options.transformFile = (file, done) => done(transformed); + + dropzone.addFile(getMockFile("text/plain", "plain.txt", ["original contents"])); + await sleep(10); + + expect(requests[0].body).toBe(transformed); + expect(await new Response(requests[0].body).text()).toBe("transformed contents"); + }); + it("should add proper Content-Type", async () => { dropzone.addFile(getMockFile()); dropzone.addFile(getMockFile("image/jpeg", "some-file.jpg", [[1, 2, 3]]));