From 1d45427195c1c5a2aee6cb19947ccb5260dbfd58 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Fri, 3 May 2024 12:50:08 +0000 Subject: [PATCH] fix(@angular/build): decode URL pathname decoding during SSG fetch Previously, missing URL decoding led to assets not being located correctly. Closes: #27590 --- .../src/utils/server-rendering/fetch-patch.ts | 3 ++- .../tests/build/prerender/http-requests-assets.ts | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/angular/build/src/utils/server-rendering/fetch-patch.ts b/packages/angular/build/src/utils/server-rendering/fetch-patch.ts index b0eb6c0e9666..aa03111fc740 100644 --- a/packages/angular/build/src/utils/server-rendering/fetch-patch.ts +++ b/packages/angular/build/src/utils/server-rendering/fetch-patch.ts @@ -39,7 +39,8 @@ export function patchFetchToLoadInMemoryAssets(): void { return originalFetch(input, init); } - const { pathname, protocol } = url; + const { protocol } = url; + const pathname = decodeURIComponent(url.pathname); if (protocol !== RESOLVE_PROTOCOL || !assetFiles[pathname]) { // Only handle relative requests or files that are in assets. diff --git a/tests/legacy-cli/e2e/tests/build/prerender/http-requests-assets.ts b/tests/legacy-cli/e2e/tests/build/prerender/http-requests-assets.ts index 40720a0953a3..64f9ca1d52b7 100644 --- a/tests/legacy-cli/e2e/tests/build/prerender/http-requests-assets.ts +++ b/tests/legacy-cli/e2e/tests/build/prerender/http-requests-assets.ts @@ -38,8 +38,11 @@ export default async function () { ], }; `, + // Add asset 'public/media.json': JSON.stringify({ dataFromAssets: true }), + 'public/media with-space.json': JSON.stringify({ dataFromAssetsWithSpace: true }), + // Update component to do an HTTP call to asset. 'src/app/app.component.ts': ` import { Component, inject } from '@angular/core'; @@ -53,16 +56,23 @@ export default async function () { imports: [CommonModule, RouterOutlet], template: \`

{{ data | json }}

+

{{ dataWithSpace | json }}

\`, }) export class AppComponent { data: any; + dataWithSpace: any; + constructor() { const http = inject(HttpClient); http.get('/media.json').subscribe((d) => { this.data = d; }); + + http.get('/media%20with-space.json').subscribe((d) => { + this.dataWithSpace = d; + }); } } `, @@ -74,4 +84,8 @@ export default async function () { 'dist/test-project/browser/index.html', /

{[\S\s]*"dataFromAssets":[\s\S]*true[\S\s]*}<\/p>/, ); + await expectFileToMatch( + 'dist/test-project/browser/index.html', + /

{[\S\s]*"dataFromAssetsWithSpace":[\s\S]*true[\S\s]*}<\/p>/, + ); }