LostBeard / SpawnDev.BlazorJS

Full Blazor WebAssembly and Javascript Interop with multithreading via WebWorkers
https://blazorjs.spawndev.com
MIT License
78 stars 6 forks source link

Wrong _frameworkPath when the location includes the index doc name #5

Closed Martin521 closed 1 year ago

Martin521 commented 1 year ago

If you include the trailing /index.html in the browser address (I have to do this in certain situations), the _framework and _content paths are no longer correct (they include the /index.html).

I guess this would need to be checked in spawndev.blazorjs.webworkers.js near line 60.

LostBeard commented 1 year ago

How does the main page location.href affect the worker location.href? I'm not sure how to reproduce the issue.

Martin521 commented 1 year ago

If you enter "www.example.com" in the browser, location.href is "https://www.example.com", even though "https://www.example.com/index.html" is served.

If you enter "www.example.com/index.html" in the browser, location.href is "https://www.example.com/index.html", and _frameworkPath in the above mentioned code becomes "https://www.example.com/index.html/_framework".

You should be able to reproduce this with any site using spawndev.blazorjs.webworkers.

But maybe I completely misunderstand what is going on.

And of course I can work around the issue, not a big thing. I just thought I bring it in here.

LostBeard commented 1 year ago

From spawndev.blazorjs.webworkers.js line 60 area...

var _frameworkPath = '';
var _appPath = '';
// This script runs in the worker context
// location.href is the location of the worker script
// location.href == 'https://localhost:7191/_content/SpawnDev.BlazorJS.WebWorkers/spawndev.blazorjs.webworkers.js?verbose=false'
if (location.href.indexOf('_content/SpawnDev.BlazorJS.WebWorkers') > 0) {
    _frameworkPath = new URL(`../../_framework/`, location.href).toString();
    _appPath = new URL(`../../`, location.href).toString();
} else {
    _frameworkPath = new URL(`_framework/`, location.href).toString();
    _appPath = new URL(`./`, location.href).toString();
}
consoleLog('_frameworkPath', _frameworkPath);
// prints https://localhost:7191/_framework/

What is the error(s) you are getting?

What is the address of the first _framework file that fails to load due to the wrong address?

Can you start your worker in verbose mode and copy paste the output?

What is your index.html base href? (<base href="/" />)

A test project would be great but I understand it's a pain. I am unable to reproduce this at the moment (trying.) If I start my debug version and load the url with index.html and them create and use a worker it works as expected.

Martin521 commented 1 year ago

Thank you for looking into it.

What is the error(s) you are getting? What is the address of the first _framework file that fails to load due to the wrong address?

Loading module from “http://mybucket....amazonaws.com/index.html/_content/SpawnDev.BlazorJS/SpawnDev.BlazorJS.lib.module.js” was blocked because of a disallowed MIME type (“text/html”).

What is your index.html base href? ()

Ah, that makes the difference. I don't have a base element in index.html (to be flexible regarding deployment). So base = location.href. Not sure if that is a use case you would consider covering. As mentioned, I can work around it.

LostBeard commented 1 year ago

Ah. I cannot fix that. That error occurs before my code runs.

By not using the base element in your index.html you are breaking some of the functionality of Blazor not limited to WebWorkers or BlazorJS. The part that WebWorkers use that it breaks is Blazor's "JS Initializers" (Link below)

"JS initializers are detected as part of the build process and imported automatically in Blazor apps." https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/startup?view=aspnetcore-7.0#javascript-initializers

SpawnDev.BlazorJS.lib.module.js is a JS Initializer for the SpawnDev.BlazorJS module and is automatically loaded by Blazor before the app is loaded.

"Important. For URLs to resolve correctly, the app must include a <base> tag (location of <head> content) with the app base path specified in the href attribute. For more information, see Host and deploy ASP.NET Core Blazor." https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/routing?view=aspnetcore-7.0

Related reference: https://learn.microsoft.com/en-us/aspnet/core/blazor/javascript-interoperability/?view=aspnetcore-7.0#inject-a-script-after-blazor-starts

LostBeard commented 1 year ago

I deploy some of my Blazor WASM apps on AWS also. I tend to use CloudFront with my own DNS but I might be able to help if you are having an issue when you use the base element.

In S3, you can set an index document so your index.html is used when no file specified. And you can even set a custom 404 page to also point at your index.html so it always uses your index.html.

https://docs.aws.amazon.com/AmazonS3/latest/userguide/IndexDocumentSupport.html https://docs.aws.amazon.com/AmazonS3/latest/userguide/CustomErrorDocSupport.html

Martin521 commented 1 year ago

Thank you for the references. That clarifies the matter.