Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I‘m using a custom tileLoadFunction in order to retrieve my tiles via an XMLHttpRequest (the reason for this is that the builtin loader doesn‘t always send the session cookie along to the server).

The loader works, however, if (e.g due to a network problem) the request for a tile fails, OpenLayers will not call the loader again for this tile.

My question now, is there a way to let OpenLayers know that the tile was not loaded successfully?

Thanks, Simon

function getTile(tile, url) 
    var xhr = new XMLHttpRequest();
    xhr.responseType = "arraybuffer";
    xhr.open('GET', url);
    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 && xhr.status === 0)
            tile.getImage().src = "";
            //console.log("error " + url)
    xhr.onload = function () {
        var arrayBufferView = new Uint8Array(this.response);
        var blob = new Blob([arrayBufferView]);
        var urlCreator = window.URL || window.webkitURL;
        var imageUrl = urlCreator.createObjectURL(blob);
        tile.getImage().src = imageUrl;
    xhr.send();
                Thank you, but I‘m not sure how this would make a difference - in the tile load function above I have already the possibility to handle the error. The problem is, what to do in order for the loading of this particular tile to be retried. By now I have adopted a hack, executing tile.load() after a timeout of 1s. Not beautiful, but functional so far.
– sober
                Apr 25, 2018 at 12:27

the cache prevents the tile from being loaded again. But you can use a trick: just set the tile loader function again by calling setTileLoadFunction, it internally clears the cache.

setTileLoadFunction(getTile)
                Thanks dube, but this can serve only as an interim workaround, as it would also cause all the existing tiles to be discarded and reloaded. In addition, in the tileLoadFunction the layer's source is not available for resetting the tileLoadFunction (especially if there are multiple map layers handled by a layer switcher).
– sober
                Apr 24, 2018 at 8:09
                Resetting all data should not concern you if your problem is doesn‘t always send the session cookie, which reads as "session not valid". But of course it is a hack and you should investigate Chase Chois suggestion.
– dube
                Apr 24, 2018 at 12:56
                I am authenticating my tiles with JWT and this solution worked perfectly for me. Thanks dube.
– mcneela86
                Aug 3, 2018 at 13:58

Late answer, but in your error catching you can set the tile state and attach an error-checking function to the tile setState event as Chase Choi noted:

if (xhr.readyState === 4 && xhr.status === 0) {
    tile.getImage().src = "";
    tile.setState(3);  //sets state to ERROR 
layer.getSource()on.("tileloaderror", handleTileLoadError); //set a timeout and run getTile again

However, I have found that a better approach is to include a retry in your request and place a limit on iterations:

const retries = {};
function getTile(tile, URL) { 
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4 && xhr.status === 0) {
        retries[src] = (retries[src] || 0) + 1);
        if (retries[src] <= 3) {
            setTimeout(() => tile.load(), retries[src] * 1000);
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.