maplibre / maplibre-gl-js

MapLibre GL JS - Interactive vector tile maps in the browser
https://maplibre.org/maplibre-gl-js/docs/
Other
6.3k stars 688 forks source link

CORS issue when loading raster tiles via file protocol #3699

Open tho-masn opened 7 months ago

tho-masn commented 7 months ago

User Story

As a user I can open an index.html file locally via the file protocol so that webp image tiles are loaded correctly.

Rationale

To give a bit of a context: Our WebApp can be downloaded as backup. The backup can be run locally without any server (just by opening the index.html). This works by intercepting all network requests. We generate the webp image tiles by ourselves and include it in our backup. However with mapLibre we couldn't figure out how to work around the CORS issues. XHR requests via the file protocol are not working, due to CORS limitations. The only solution would be to work with HTML image tags, but this is not supported by mapLibre (I think openLayers does it this way).

Is there any known workaround?

Impact

We can't integrate the maps in our backups, which leads to an inconsistent state.

EDIT: Added a minimal reproduction example: reproduction.zip openlayers-example.zip

HarelM commented 7 months ago

Isn't this a duplicate of #3680?

tho-masn commented 7 months ago

Not sure if the root cause is the same, I'm not too much into the maplibre codebase. In #3680 it's about vector tiles, in my case it's about raster tiles. However trying the fix doesn't resolve the issue for raster tiles. Is this use case supported in general?

@HarelM: I've added a minimal reproduction to the description

HarelM commented 7 months ago

How did you test the fix? Did you build the version locally?

tho-masn commented 7 months ago

Exactly. From what I could see, the function actor.receive from #3680 never gets called when new tiles are requested.

HarelM commented 6 months ago

I get the following console error in chrome when using 4.0.1: image

I don't think this is a library issue but a browser security limitation. Network tab does seem to try and fetch the file.

Not sure there's anything I can do to solve this as part of this library. Did it ever worked (i.e. with previous versions)?

tho-masn commented 6 months ago

I also agree that this is a browser security limitation. I've added an openlayers example to the description. This example also works with the file protocol but it works there.

I'm not too familiar with maplibre and all the settings. Maybe there are specific headers missing?

HarelM commented 6 months ago

I'm not too familiar with open layers but IIRC open layers are using html img elements while maplibre is using the webgl canvas and GPU and these have different permission when it comes to raster images. I don't fully understand the use case, problem statement and what you are trying to achieve, so I'm not sure there's an issue here.

oberhamsi commented 3 months ago

i would say this is a cantfix since file:// doesn't allow CORS headers and browser security requires them for canvas access.

it might be possible to start the browser with options/flags to ignore those security settings.

wipfli commented 3 months ago

If you only have a small amount of data like a few megabytes of raster tiles, then you might be able to use addProtocol and base64 encoded raster tiles that you serve out from the addProtocol function.

wipfli commented 3 months ago

I made a small demo with addProtocol and base64 encoded a tile here: https://jsbin.com/bobifok/edit?html,output