[GIS] Tiles on SSL website loading over http

arcgis-javascript-apiarcgis-server

I have an application on a SLL domain. Loading all the ArcGIS Javascript files is correctly done over https. But when actually using the application, the tiles of the basemap are loaded over http, resulting in security warnings in firefox en chrome. You can see it working at https://topografieindeklas.nl/topotrainer/nederland/.

Edit: For debugging I isolated the script at https://topografieindeklas.nl/SSLtest.php. The code would be down to snippet below (I know this is legacy code; AMD made no difference whoever).

Edit2: from there, it becomes more clear where things go wrong. Looking at the JSON url, the tile sub-servers are having http instead of https!

Edit3: As it turns out, this is caused by a Bug on Esri's side. Their planing to fix it in the March release of ArcGIS Online. As a workaround a Proxy is suggested.

What could be causing the tiles being loaded over http, while the rest of the page is loaded over https?

<link rel="stylesheet" href="https://js.arcgis.com/3.7/js/dojo/dijit/themes/claro/claro.css">
<link rel="stylesheet" href="https://js.arcgis.com/3.7/js/esri/css/esri.css">
<script type="text/javascript" src="https://js.arcgis.com/3.7/"></script>
<style type="text/css">
#map{
  box-shadow:0 1px 3px rgba(0,0,0,0.5);
  -moz-box-shadow:0 1px 3px rgba(0,0,0,0.5);
  -webkit-box-shadow:0 1px 3px rgba(0,0,0,0.5);
  border:1px solid #CDCDCD;

}</style>
<script>
dojo.require("esri.map");
dojo.require("esri.layers.FeatureLayer");
dojo.require("esri.tasks.query");
dojo.require("dijit.layout.BorderContainer");
dojo.require("dijit.layout.ContentPane");
function createMap(){
  var basemapURL="https://tiles.arcgis.com/tiles/nSZVuSZjHpEZZbRo/arcgis/rest/services/Topografie_in_de_klas_nederland_ondergrond/MapServer";
  var map=new esri.Map("map",{zoom:7,center:[5.12,52.30]});
  map.addLayer(new esri.layers.ArcGISTiledMapServiceLayer(basemapURL));
  var infoTemplate=new esri.InfoTemplate("${NAME}",'Provincie <a href="https://topografieindeklas.nl/wp-content/themes/topografieindeklas/topotrainer/nederland/${Provincie}">${Provincie} oefenen</a>');
  contentFeatureLayer=new esri.layers.FeatureLayer('https://services.arcgis.com/nSZVuSZjHpEZZbRo/ArcGIS/rest/services/Topografie_in_de_klas_nederland/FeatureServer/0',
   {mode:esri.layers.FeatureLayer.ON_DEMAND,
   outFields:["*"],infoTemplate:infoTemplate});
   contentFeatureLayer.setDefinitionExpression("Type='Provincie'");
   map.addLayer(contentFeatureLayer);
   dojo.connect(map,"onLoad",function(){
     dojo.connect(map,"onMouseOver",map,"reposition");
     map.infoWindow.resize(200,100);});
   dojo.connect(contentFeatureLayer,"onMouseOver",function(evt){
     map.setMapCursor("pointer");});
   dojo.connect(contentFeatureLayer,"onMouseOut",function(evt){
     map.graphics.clear();
     map.setMapCursor("default")});
   return map;
}
dojo.ready(createMap);
</script>
<div id="mainMapWindow" dojotype="dijit.layout.BorderContainer" design="headline" gutters="false" >
<div id="map" dojotype="dijit.layout.ContentPane" region="center" ></div></div>

Best Answer

The ArcGIS JavaScript API will use the tiled service's tileServers array to fetch tiles. You can override the tile server URLs in a function connected to the map's onLoad event:

 dojo.connect(map,"onLoad",function(){
    var tiledLayer = map.getLayer(map.layerIds[0]);
    for (ts = 0; ts < tiledLayer.tileServers.length; ts++) {
        if (tiledLayer.tileServers[ts].indexOf("http://") == 0) {
            tiledLayer.tileServers[ts] = tiledLayer.tileServers[ts].replace("http://", "https://");
        }
    }

    dojo.connect(map,"onMouseOver",map,"reposition");
    map.infoWindow.resize(200,100);});

 });

Fetching the tiles over HTTPS will be slightly slower due to the protocol overhead but should eliminate your browser warnings.