diff --git a/playground/app/providers.ts b/playground/app/providers.ts index d80670711..0a05c307d 100644 --- a/playground/app/providers.ts +++ b/playground/app/providers.ts @@ -93,6 +93,12 @@ export const providers: Provider[] = [ height: 300, link: 'https://unsplash.com/@omidarmin?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText', }, + { + src: '/images/test+plus.png', + from: 'Filename with + (issue #1378)', + width: 300, + height: 300, + }, ], }, // Aliyun diff --git a/playground/public/images/test+plus.png b/playground/public/images/test+plus.png new file mode 100644 index 000000000..235232eae Binary files /dev/null and b/playground/public/images/test+plus.png differ diff --git a/src/runtime/server/routes/_ipx.ts b/src/runtime/server/routes/_ipx.ts index defcd87cf..3add17f0d 100644 --- a/src/runtime/server/routes/_ipx.ts +++ b/src/runtime/server/routes/_ipx.ts @@ -31,11 +31,17 @@ export default lazyEventHandler(() => { const ipx = createIPX(ipxOptions) const nodeHandler = createIPXNodeHandler(ipx, { parseURL(url) { - const parsedURL = new URL(url) + const parsedURL = new URL(url, 'http://localhost') let pathname = parsedURL.pathname if (baseURL && (pathname === baseURL || pathname.startsWith(`${baseURL}/`))) { pathname = pathname.slice(baseURL.length) || '/' } + try { + pathname = decodeURI(pathname) + } + catch { + // Keep original pathname if decoding fails. + } return parseIPXURL(parsedURL.origin + pathname + parsedURL.search) }, }) diff --git a/test/e2e/__snapshots__/ipx.json5 b/test/e2e/__snapshots__/ipx.json5 index 9ed913a9d..b601e7220 100644 --- a/test/e2e/__snapshots__/ipx.json5 +++ b/test/e2e/__snapshots__/ipx.json5 @@ -5,6 +5,7 @@ "/_ipx/s_300x300/images/colors.jpg", "/_ipx/s_300x300/images/everest.jpg", "/_ipx/s_300x300/images/tacos.svg", + "/_ipx/s_300x300/images/test%2Bplus.png", "/_ipx/s_300x300/unsplash/photo-1606112219348-204d7d8b94ee", ], "sources": [ @@ -14,5 +15,6 @@ "/_ipx/s_300x300/images/everest.jpg", "/_ipx/s_300x300/images/tacos.svg", "/_ipx/s_300x300/unsplash/photo-1606112219348-204d7d8b94ee", + "/_ipx/s_300x300/images/test%2Bplus.png", ], } \ No newline at end of file diff --git a/test/e2e/generate.test.ts b/test/e2e/generate.test.ts index 4bb300721..0ab1c139f 100644 --- a/test/e2e/generate.test.ts +++ b/test/e2e/generate.test.ts @@ -40,12 +40,14 @@ describe('ipx provider', () => { "_ipx/s_300x300/images/colors.jpg", "_ipx/s_300x300/images/everest.jpg", "_ipx/s_300x300/images/tacos.svg", + "_ipx/s_300x300/images/test%2Bplus.png", "_ipx/s_300x300/unsplash/photo-1606112219348-204d7d8b94ee", "_ipx/s_600x600/images/colors-layer-config.jpg", "_ipx/s_600x600/images/colors-layer.jpg", "_ipx/s_600x600/images/colors.jpg", "_ipx/s_600x600/images/everest.jpg", "_ipx/s_600x600/images/tacos.svg", + "_ipx/s_600x600/images/test%2Bplus.png", "_ipx/s_600x600/unsplash/photo-1606112219348-204d7d8b94ee", ] `)