Skip to content

Commit c0cee2f

Browse files
committed
Fix client navigation: always use enhanced nav for not found rendering, unless user explicitly disbled it.
1 parent 29b5322 commit c0cee2f

File tree

4 files changed

+15
-52
lines changed

4 files changed

+15
-52
lines changed

src/Components/Endpoints/src/Rendering/EndpointHtmlRenderer.Streaming.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -229,23 +229,24 @@ private static void HandleExceptionAfterResponseStarted(HttpContext httpContext,
229229
private static void HandleNotFoundAfterResponseStarted(TextWriter writer, HttpContext httpContext, string notFoundUrl)
230230
{
231231
writer.Write("<blazor-ssr><template type=\"not-found\"");
232-
WriteResponseTemplate(writer, httpContext, notFoundUrl);
232+
WriteResponseTemplate(writer, httpContext, notFoundUrl, useEnhancedNav: true);
233233
}
234234

235235
private static void HandleNavigationAfterResponseStarted(TextWriter writer, HttpContext httpContext, string destinationUrl)
236236
{
237237
writer.Write("<blazor-ssr><template type=\"redirection\"");
238-
WriteResponseTemplate(writer, httpContext, destinationUrl);
238+
bool useEnhancedNav = IsProgressivelyEnhancedNavigation(httpContext.Request);
239+
WriteResponseTemplate(writer, httpContext, destinationUrl, useEnhancedNav);
239240
}
240241

241-
private static void WriteResponseTemplate(TextWriter writer, HttpContext httpContext, string destinationUrl)
242+
private static void WriteResponseTemplate(TextWriter writer, HttpContext httpContext, string destinationUrl, bool useEnhancedNav)
242243
{
243244
if (HttpMethods.IsPost(httpContext.Request.Method))
244245
{
245246
writer.Write(" from=\"form-post\"");
246247
}
247248

248-
if (IsProgressivelyEnhancedNavigation(httpContext.Request))
249+
if (useEnhancedNav)
249250
{
250251
writer.Write(" enhanced=\"true\"");
251252
}

src/Components/Web.JS/src/Rendering/StreamingRendering.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,16 @@ class BlazorStreamingUpdate extends HTMLElement {
4545
insertStreamingContentIntoDocument(componentId, node.content);
4646
}
4747
} else {
48+
const isEnhancedNav = node.getAttribute('enhanced') === 'true';
4849
switch (node.getAttribute('type')) {
4950
case 'redirection':
50-
redirect(node, true);
51+
redirect(node, true, isEnhancedNav);
5152
break;
5253
case 'not-found':
53-
redirect(node, false);
54+
// not-found template has enhanced nav set to true by default,
55+
// check for the options to avoid overriding user settings
56+
const useEnhancedNav = isEnhancedNav && enableDomPreservation;
57+
redirect(node, false, useEnhancedNav);
5458
break;
5559
case 'error':
5660
// This is kind of brutal but matches what happens without progressive enhancement
@@ -63,12 +67,11 @@ class BlazorStreamingUpdate extends HTMLElement {
6367
}
6468
}
6569

66-
function redirect(node: HTMLTemplateElement, changeUrl: boolean): void {
70+
function redirect(node: HTMLTemplateElement, changeUrl: boolean, isEnhancedNav: boolean): void {
6771
// We use 'replace' here because it's closest to the non-progressively-enhanced behavior, and will make the most sense
6872
// if the async delay was very short, as the user would not perceive having been on the intermediate page.
6973
const destinationUrl = toAbsoluteUri(node.content.textContent!);
7074
const isFormPost = node.getAttribute('from') === 'form-post';
71-
const isEnhancedNav = node.getAttribute('enhanced') === 'true';
7275
if (isEnhancedNav && isWithinBaseUriSpace(destinationUrl)) {
7376
// At this point the destinationUrl might be an opaque URL so we don't know whether it's internal/external or
7477
// whether it's even going to the same URL we're currently on. So we don't know how to update the history.

src/Components/test/E2ETest/ServerRenderingTests/NoInteractivityTest.cs

Lines changed: 3 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -127,16 +127,11 @@ private void AssertNotFoundPageRendered()
127127
private void AssertUrlNotChanged(string expectedUrl) =>
128128
Browser.True(() => Browser.Url.Contains(expectedUrl), $"Expected URL to contain '{expectedUrl}', but found '{Browser.Url}'");
129129

130-
private void AssertUrlChanged(string urlPart) =>
131-
Browser.False(() => Browser.Url.Contains(urlPart), $"Expected URL not to contain '{urlPart}', but found '{Browser.Url}'");
132-
133130
[Theory]
134131
[InlineData(true, true)]
135132
[InlineData(true, false)]
136133
[InlineData(false, true)]
137134
[InlineData(false, false)]
138-
// When response has not started, it does not matter how we arrive the the page setting the not found status code.
139-
// We can navigate straight to the testing page, skipping the index page.
140135
public void NotFoundSetOnInitialization_ResponseNotStarted_SSR(bool hasReExecutionMiddleware, bool hasCustomNotFoundPageSet)
141136
{
142137
string reexecution = hasReExecutionMiddleware ? "/reexecution" : "";
@@ -154,32 +149,18 @@ public void NotFoundSetOnInitialization_ResponseNotStarted_SSR(bool hasReExecuti
154149
AssertUrlNotChanged(testUrl);
155150
}
156151

157-
// If the response has started, it matters how we arrive the the page setting the not found status code
158-
// because we are rendering client-side. In browser-initiated navigation and form submissions, the headers
159-
// don't contain enhanced-nav and we redirect to the not found page. In link clicking navigation,
160-
// the headers contain enhanced-nav, redirection is not needed and the original url is preserved.
161-
162152
[Theory]
163153
[InlineData(true, true)]
164154
[InlineData(true, false)]
165155
[InlineData(false, true)]
166156
[InlineData(false, false)]
167-
// enhanced navigation is switched off for browser navigation
168157
public void NotFoundSetOnInitialization_ResponseStarted_BrowserNavigation_SSR(bool hasReExecutionMiddleware, bool hasCustomNotFoundPageSet)
169158
{
170159
string reexecution = hasReExecutionMiddleware ? "/reexecution" : "";
171160
string testUrl = $"{ServerPathBase}{reexecution}/set-not-found-ssr-streaming?useCustomNotFoundPage={hasCustomNotFoundPageSet}";
172161
Navigate(testUrl);
173162
AssertNotFoundRendered_ResponseStarted_Or_POST(hasReExecutionMiddleware, hasCustomNotFoundPageSet, testUrl);
174-
bool throwsException = !hasCustomNotFoundPageSet && !hasReExecutionMiddleware;
175-
if (throwsException)
176-
{
177-
AssertUrlNotChanged(testUrl);
178-
}
179-
else
180-
{
181-
AssertUrlChanged(testUrl);
182-
}
163+
AssertUrlNotChanged(testUrl);
183164
}
184165

185166
private void AssertNotFoundRendered_ResponseStarted_Or_POST(bool hasReExecutionMiddleware, bool hasCustomNotFoundPageSet, string testUrl)
@@ -204,7 +185,6 @@ private void AssertNotFoundRendered_ResponseStarted_Or_POST(bool hasReExecutionM
204185
[InlineData(true, false)]
205186
[InlineData(false, true)]
206187
[InlineData(false, false)]
207-
// enhanced navigation is switched on for link navigation
208188
public void NotFoundSetOnInitialization_ResponseStarted_LinkNavigation_SSR(bool hasReExecutionMiddleware, bool hasCustomNotFoundPageSet)
209189
{
210190
string testUrl = NavigateByLinkToPageTestingNotFound("Sets", hasReExecutionMiddleware, hasCustomNotFoundPageSet);
@@ -229,8 +209,6 @@ private string NavigateByLinkToPageTestingNotFound(string action, bool hasReExec
229209
[InlineData(true, false)]
230210
[InlineData(false, true)]
231211
[InlineData(false, false)]
232-
// NotFound triggered by POST cannot get rendered in the same batch and we rely on the client to render it
233-
// However, because it is triggered by form POST, it won't have enhanced-nav headers
234212
public void NotFoundSetOnFormSubmit_ResponseNotStarted_SSR(bool hasReExecutionMiddleware, bool hasCustomNotFoundPageSet)
235213
{
236214
string reexecution = hasReExecutionMiddleware ? "/reexecution" : "";
@@ -239,15 +217,7 @@ public void NotFoundSetOnFormSubmit_ResponseNotStarted_SSR(bool hasReExecutionMi
239217
Browser.FindElement(By.Id("not-found-form")).FindElement(By.TagName("button")).Click();
240218

241219
AssertNotFoundRendered_ResponseStarted_Or_POST(hasReExecutionMiddleware, hasCustomNotFoundPageSet, testUrl);
242-
bool throwsException = !hasCustomNotFoundPageSet && !hasReExecutionMiddleware;
243-
if (throwsException)
244-
{
245-
AssertUrlNotChanged(testUrl);
246-
}
247-
else
248-
{
249-
AssertUrlChanged(testUrl);
250-
}
220+
AssertUrlNotChanged(testUrl);
251221
}
252222

253223
[Theory]
@@ -263,15 +233,7 @@ public void NotFoundSetOnFormSubmit_ResponseStarted_SSR(bool hasReExecutionMiddl
263233
Browser.FindElement(By.Id("not-found-form")).FindElement(By.TagName("button")).Click();
264234

265235
AssertNotFoundRendered_ResponseStarted_Or_POST(hasReExecutionMiddleware, hasCustomNotFoundPageSet, testUrl);
266-
bool throwsException = !hasCustomNotFoundPageSet && !hasReExecutionMiddleware;
267-
if (throwsException)
268-
{
269-
AssertUrlNotChanged(testUrl);
270-
}
271-
else
272-
{
273-
AssertUrlChanged(testUrl);
274-
}
236+
AssertUrlNotChanged(testUrl);
275237
}
276238

277239
private void AssertNotFoundFragmentRendered() =>

src/Shared/E2ETesting/WaitAssert.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,6 @@ public static void True(this IWebDriver driver, Func<bool> actual, TimeSpan time
4040
public static void True(this IWebDriver driver, Func<bool> actual, string message)
4141
=> WaitAssertCore(driver, () => Assert.True(actual(), message));
4242

43-
public static void False(this IWebDriver driver, Func<bool> actual, string message)
44-
=> WaitAssertCore(driver, () => Assert.False(actual(), message));
45-
4643
public static void False(this IWebDriver driver, Func<bool> actual)
4744
=> WaitAssertCore(driver, () => Assert.False(actual()));
4845

0 commit comments

Comments
 (0)