diff --git a/.changeset/nasty-squids-collect.md b/.changeset/nasty-squids-collect.md new file mode 100644 index 000000000..1a85c0057 --- /dev/null +++ b/.changeset/nasty-squids-collect.md @@ -0,0 +1,5 @@ +--- +"openapi-fetch": patch +--- + +Fix 'Content-Type' header being removed from requests with multipart/form-data body diff --git a/packages/openapi-fetch/src/index.js b/packages/openapi-fetch/src/index.js index c2d5b7e24..b9a1bcc37 100644 --- a/packages/openapi-fetch/src/index.js +++ b/packages/openapi-fetch/src/index.js @@ -65,14 +65,14 @@ export default function createClient(clientOptions) { if (requestInit.body) { requestInit.body = bodySerializer(requestInit.body); } + // remove `Content-Type` if serialized body is FormData; browser will correctly set Content-Type & boundary expression + if (requestInit.body instanceof FormData) { + requestInit.headers.delete("Content-Type"); + } let request = new Request( createFinalURL(url, { baseUrl, params, querySerializer }), requestInit, ); - // remove `Content-Type` if serialized body is FormData; browser will correctly set Content-Type & boundary expression - if (requestInit.body instanceof FormData) { - request.headers.delete("Content-Type"); - } // middleware (request) const mergedOptions = { baseUrl, diff --git a/packages/openapi-fetch/test/index.test.ts b/packages/openapi-fetch/test/index.test.ts index 9d8c27f5c..5fe7506b3 100644 --- a/packages/openapi-fetch/test/index.test.ts +++ b/packages/openapi-fetch/test/index.test.ts @@ -937,9 +937,9 @@ describe("client", () => { const req = fetchMocker.mock.calls[0][0]; // note: this is FormData, but Node.js doesn’t handle new Request() properly with formData bodies. So this is only in tests. expect(req.body).toBeInstanceOf(Buffer); - - // TODO: `vitest-fetch-mock` does not add the boundary to the Content-Type header like browsers do, so we expect the header to be null instead - expect(req.headers.get("Content-Type")).toBeNull(); + expect((req.headers as Headers).get("Content-Type")).toBe( + "text/plain;charset=UTF-8", + ); }); // Node Requests eat credentials (no cookies), but this works in frontend diff --git a/packages/openapi-fetch/test/v7-beta.test.ts b/packages/openapi-fetch/test/v7-beta.test.ts index 06a96489b..7900dc30b 100644 --- a/packages/openapi-fetch/test/v7-beta.test.ts +++ b/packages/openapi-fetch/test/v7-beta.test.ts @@ -946,9 +946,9 @@ describe("client", () => { const req = fetchMocker.mock.calls[0][0]; // note: this is FormData, but Node.js doesn’t handle new Request() properly with formData bodies. So this is only in tests. expect(req.body).toBeInstanceOf(Buffer); - - // TODO: `vitest-fetch-mock` does not add the boundary to the Content-Type header like browsers do, so we expect the header to be null instead - expect((req.headers as Headers).get("Content-Type")).toBeNull(); + expect((req.headers as Headers).get("Content-Type")).toBe( + "text/plain;charset=UTF-8", + ); }); // Node Requests eat credentials (no cookies), but this works in frontend