0

I am trying to load a layer on the OSM map using OL. The service which I have requires the authentication header, I have written the code but somehow it's not working. Here is my code

function customLoader(tile, src) {
        var client = new XMLHttpRequest();
        client.open('GET', src);
        client.setRequestHeader("Ocp-Apim-Subscription-Key","XXXXXXXXXXXXXX");
        client.onload = function() {
          tile.getImage().src = src;
        };
        client.send();
      }
      var layers = [
        new ol.layer.Tile({
          source: new ol.source.OSM()
        }),
        new ol.layer.Tile({
          extent: [-425988.3826589292,6390953.66876267,161047.99457094132,6677439.650775372],
          source: new ol.source.TileWMS({
            url: 'https://url.com/WMSServer',
            tileLoadFunction: customLoader,
            params: {'LAYERS': '21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0', 'TILED': true},
            serverType: 'WMSServer',
            transition: 0
          })
        })
      ];
      var map = new ol.Map({
        layers: layers,
        target: 'map',
        view: new ol.View({
          center: [-4.095013, 56.550473],
          zoom: 4
        })
      });

I am not sure what I am doing wrong.

Tony
  • 618
  • 12
  • 27
Piyush
  • 492
  • 5
  • 22
  • See https://stackoverflow.com/questions/32914173/how-to-add-a-http-header-to-openlayers3-requests You need to set the image src to the result of the xhr, not the url used iby the xhr. – Mike Sep 09 '20 at 08:45
  • @Mike when I am loading as base64 Tiles are not getting loaded – Piyush Sep 09 '20 at 08:57

1 Answers1

0

I cannot get the base64 method to work either. It would be better to use the object url method from https://openlayers.org/en/latest/apidoc/module-ol_Tile.html#~LoadFunction (but note that object urls can cause memory leaks if not revoked)

<!doctype html>
<html lang="en">
  <head>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.4.3/css/ol.css" type="text/css">
    <style>
      html, body, .map {
        margin: 0;
        padding: 0;
        width: 100%;
        height: 100%;
      }
    </style>
    <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.4.3/build/ol.js"></script>
  </head>
  <body>
    <div id="map" class="map"></div>
    <script type="text/javascript">
      var map = new ol.Map({
        target: 'map',
        layers: [
          new ol.layer.Tile({
            source: new ol.source.OSM({
              url: 'https://{a-c}.tile.opentopomap.org/{z}/{x}/{y}.png',
              maxZoom: 17,
              tileLoadFunction: function (tile, src) {
                var xhr = new XMLHttpRequest();
                xhr.responseType = 'blob';
                xhr.addEventListener('load', function (evt) {
                  var data = this.response;
                  if (data !== undefined) {
                    var url = URL.createObjectURL(data);
                    tile.getImage().addEventListener('load', function () {
                      URL.revokeObjectURL(url);
                    });
                    tile.getImage().src = url;
                  } else {
                    tile.setState(3);
                  }
                });
                xhr.addEventListener('error', function () {
                  tile.setState(3);
                });
                xhr.open('GET', src);
                xhr.send();
              }
            })
          })
        ],
        view: new ol.View({
          center: [0, 0],
          zoom: 2
        })
      });
    </script>
  </body>
</html>
Mike
  • 16,042
  • 2
  • 14
  • 30
  • I got the result, I was doing same thing but I am not revoking the url. I am facing another error. How can I solve the CORS policy issue in this condition – Piyush Sep 09 '20 at 10:44
  • 1
    Images can be loaded directly without cross original access (the only issue is tainted canvas which cannot be export) but xhr only works when the server allows cross original access. If it cannot be changed on the remote server you will need to use a proxy. – Mike Sep 09 '20 at 10:57