diff --git a/src/utils.ts b/src/utils.ts index 3bc0dbf5..0fbed223 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -50,6 +50,7 @@ const textTypes = new Set([ ]); const JSON_RE = /^application\/(?:[\w!#$%&*.^`~-]*\+)?json(;.+)?$/i; +const XML_RE = /^[\w!#$%&*.^`~-]+\/(?:[\w!#$%&*.^`~-]*\+)?xml(;.+)?$/i; // This provides reasonable defaults for the correct parser based on Content-Type header. export function detectResponseType(_contentType = ""): ResponseType { @@ -75,7 +76,11 @@ export function detectResponseType(_contentType = ""): ResponseType { return "stream"; } - if (textTypes.has(contentType) || contentType.startsWith("text/")) { + if ( + textTypes.has(contentType) || + XML_RE.test(contentType) || + contentType.startsWith("text/") + ) { return "text"; } diff --git a/test/index.test.ts b/test/index.test.ts index 5ac20b07..955d8965 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -47,6 +47,13 @@ describe("ofetch", () => { event.res.headers.set("Content-Type", "application/octet-stream"); return new Blob(["binary"]); }) + .all("/content-type", (event) => { + event.res.headers.set( + "Content-Type", + event.url.searchParams.get("type") || "text/plain" + ); + return ""; + }) .all( "/403", () => new HTTPError({ status: 403, statusMessage: "Forbidden" }) @@ -110,6 +117,23 @@ describe("ofetch", () => { expect(await $fetch(getURL("binary"))).to.be.instanceOf(Blob); }); + it("returns text for xml content-types", async () => { + for (const type of [ + "application/xml", + "application/rss+xml", + "application/atom+xml", + "application/xhtml+xml", + "image/svg+xml", + "model/step+xml", + "message/imdn+xml", + "application/rss+xml; charset=utf-8", + ]) { + expect( + await $fetch(getURL(`content-type?type=${encodeURIComponent(type)}`)) + ).to.equal(""); + } + }); + it("baseURL", async () => { expect(await $fetch("/x?foo=123", { baseURL: getURL("url") })).to.equal( "/url/x?foo=123"