Skip to content

hotreload breaks blazor webassembly with asp and user defined base path - missing blazor-hotreload.js returns 404 #35555

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
vsfeedback opened this issue Aug 20, 2021 · 2 comments · Fixed by #35737
Assignees
Labels
area-blazor Includes: Blazor, Razor Components Author: Migration Bot 🤖 The issue was created by a issue mover bot. The author may not be the actual author. investigate
Milestone

Comments

@vsfeedback
Copy link

This issue has been moved from a ticket on Developer Community.


[regression] [worked-in:VS 2022 Preview 6]
In visual studio 2022 latest pre-release (7), When the user changes the base path for the Blazor web assembly application using asp.net core hosting, there is a run-time error in the browser because the GET request for blazor-hotreload.js returns a 404 error. This stops Blazor in the client so I cannot run or debug.

Analysis
It looks like the base path is added to the front of the blazor-hotreload.js GET url. Without this base path change, it looks like Visual studio (or some other code) handles the request for blazor-hotreload.js before any user asp.net code gets run. That code seems to expect only the URL: "/_framework/blazor-hotreload.js". When it sees the URL "/UserPath/_framework/blazor-hotreload.js", then it sends the request to the user's asp.net code to handle. Since my code doesn't handle blazor-hotreload.js, it returns the 404 error.

Workaround,
I put in special handling (in my code) to return blazor-hotreload.js. That stopped the client side Blazor code from exiting with the 404 error, but then the blazor-hotreload.js code runs a "fetch('_framework/blazor-hotreload',...". This sends a request for "/UserPath/_framework/blazor-hotreload" which my code doesn't know what to do with either. To fix this second issue, I changed my local copy of blazor-hotreload.js to "fetch('/_framework/blazor-hotreload',...", with an extra "/" at the front. This combination lets Visual studio handle the request and works around the problem.

My code to handle blazor-hotreload.js looks like this:

app. MapWhen(
context => {
var path = context. Request.Path.Value.ToLower();
return
path. EndsWith("/blazor-hotreload.js");
},
config => config. UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
@"\wwwroot"),
RequestPath = "/_framework"
}));

I then put this code under \wwwroot\blazor-hotreload.js

export function receiveHotReload() {
return BINDING.js_to_mono_obj(new Promise((resolve) => receiveHotReloadAsync().then(resolve(0))));
}

async function receiveHotReloadAsync() {
const cache = window.sessionStorage.getItem('blazor-webassembly-cache');
let headers;
if (cache) {
headers = { 'if-none-match': cache.etag };
}
const response = await fetch('/_framework/blazor-hotreload', { headers });
if (response.status === 200) {
const deltas = await response.json();
if (deltas) {
try {
deltas.forEach(d => window. Blazor._internal.applyHotReload(d.moduleId, d.metadataDelta, d.ilDelta));
} catch (error) {
console.warn(error);
return;
}
}
}
}

Steps to Reproduce

Open and run the attached project's BlazorApp1.Server

or follow these steps to make your own.

  1. Create a new project using Blazor Webassembly
    a) Check the Checkbox for "ASP.NET code hosted"

  2. Set the startup project to be the . Server project.

  3. Run to make sure everything is working. So far everything should work.

  4. In the . Client project edit wwwroot/index.html and change the line:

    to

  5. in the . Server project edit program.cs and add the line:
    app. UsePathBase("/UserPath");
    just under the line that says "var app = builder. Build();"

  6. Run again, but when the browser opens up, change the URL path by adding "UserPath" to the end: eg https://localhost:/UserPath

The browser will show an error and in the console, you will see this error:

blazor.webassembly.js:1 GET https://localhost:5001/UserPath/_framework/blazor-hotreload.js net::ERR_ABORTED 404
(anonymous) @ blazor.webassembly.js:1
beginInvokeJSFromDotNet @ blazor.webassembly.js:1
blazor.webassembly.js:1 System.AggregateException: One or more errors occurred. (Failed to fetch dynamically imported module: https://localhost:5001/UserPath/_framework/blazor-hotreload.js
TypeError: Failed to fetch dynamically imported module: https://localhost:5001/UserPath/_framework/blazor-hotreload.js)


Original Comments

Feedback Bot on 8/19/2021, 07:03 PM:

We have directed your feedback to the appropriate engineering team for further evaluation. The team will review the feedback and notify you about the next steps.


Original Solutions

(no solutions)

@ghost ghost added the Author: Migration Bot 🤖 The issue was created by a issue mover bot. The author may not be the actual author. label Aug 20, 2021
@LostBeard
Copy link
Contributor

I can confirm this error exists with a non-root base href and Blazor WASM apps. Issue started with preview 7.

@LostBeard
Copy link
Contributor

Temporary workaround:
Create a folder in your project wwwroot folder named "_framework" and then create a file named "blazor-hotreload.js" in that folder. Paste the contents from the original "blazor-hotreload.js" file (found below if needed) to that file. Your app should now not complain about the missing file.

---------- blazor-hotreload.js contents below this line ----------

export function receiveHotReload() {
    return BINDING.js_to_mono_obj(new Promise((resolve) => receiveHotReloadAsync().then(resolve(0))));
}

async function receiveHotReloadAsync() {
    const cache = window.sessionStorage.getItem('blazor-webassembly-cache');
    let headers;
    if (cache) {
        headers = { 'if-none-match': cache.etag };
    }
    const response = await fetch('_framework/blazor-hotreload', { headers });
    if (response.status === 200) {
        const deltas = await response.json();
        if (deltas) {
            try {
                deltas.forEach(d => window.Blazor._internal.applyHotReload(d.moduleId, d.metadataDelta, d.ilDelta));
            } catch (error) {
                console.warn(error);
                return;
            }
        }
    }
}

@Pilchie Pilchie added the area-blazor Includes: Blazor, Razor Components label Aug 23, 2021
@pranavkm pranavkm self-assigned this Aug 24, 2021
@pranavkm pranavkm added this to the 6.0-rc2 milestone Aug 24, 2021
pranavkm added a commit that referenced this issue Aug 25, 2021
The middleware that we inject always listens to the root of the app. While this might not play very nicely if the app
is running off a virtual path, listening to the root is what we do with the aspnet-browser-refresh.js script and we've had no issue
reports with it thus far.

Fixes #35555
pranavkm added a commit that referenced this issue Aug 25, 2021
The middleware that we inject always listens to the root of the app. While this might not play very nicely if the app
is running off a virtual path, listening to the root is what we do with the aspnet-browser-refresh.js script and we've had no issue
reports with it thus far.

Fixes #35555
pranavkm added a commit that referenced this issue Sep 22, 2021
The middleware that we inject always listens to the root of the app. While this might not play very nicely if the app
is running off a virtual path, listening to the root is what we do with the aspnet-browser-refresh.js script and we've had no issue
reports with it thus far.

Fixes #35555
wtgodbe pushed a commit that referenced this issue Sep 23, 2021
The middleware that we inject always listens to the root of the app. While this might not play very nicely if the app
is running off a virtual path, listening to the root is what we do with the aspnet-browser-refresh.js script and we've had no issue
reports with it thus far.

Fixes #35555
pranavkm added a commit that referenced this issue Sep 23, 2021
The middleware that we inject always listens to the root of the app. While this might not play very nicely if the app
is running off a virtual path, listening to the root is what we do with the aspnet-browser-refresh.js script and we've had no issue
reports with it thus far.

Fixes #35555
wtgodbe pushed a commit that referenced this issue Sep 23, 2021
The middleware that we inject always listens to the root of the app. While this might not play very nicely if the app
is running off a virtual path, listening to the root is what we do with the aspnet-browser-refresh.js script and we've had no issue
reports with it thus far.

Fixes #35555
BrennanConroy added a commit that referenced this issue Sep 24, 2021
* Update WiX to signed build (#36865)

- #12078

* Always download blazor-hotreload.js from app root (#36897)

The middleware that we inject always listens to the root of the app. While this might not play very nicely if the app
is running off a virtual path, listening to the root is what we do with the aspnet-browser-refresh.js script and we've had no issue
reports with it thus far.

Fixes #35555

* Improve Results.Problem and Results.ValidationProblem APIs (#36856)

* [release/6.0-rc2] Update sdk to 6.0.100-rc.2.21470.55 (#36783)

* Update sdk to 6.0.100-rc.2.21470.55

Co-authored-by: Will Godbe <[email protected]>

Co-authored-by: Doug Bunting <[email protected]>
Co-authored-by: Pranav K <[email protected]>
Co-authored-by: Safia Abdalla <[email protected]>
Co-authored-by: Stephen Halter <[email protected]>
Co-authored-by: Will Godbe <[email protected]>
Co-authored-by: Brennan <[email protected]>
@ghost ghost locked as resolved and limited conversation to collaborators Sep 24, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-blazor Includes: Blazor, Razor Components Author: Migration Bot 🤖 The issue was created by a issue mover bot. The author may not be the actual author. investigate
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants