2

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>
1

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.

  • Hi Mwalker, thanks for your example. I think this will solve my problem. But I can't get it working in the example above. How should I format it / should i place it? – Dennis Hunink Jan 1 '14 at 13:21
  • In your example above, you could put the code into the existing anonymous function that's attached to the map's load event. You may have to add some more handling code to ensure that you get the correct service from map.getLayer - this example will assume that the first layer is the tiled layer we want to change. – mwalker Jan 2 '14 at 17:07
0

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.

It can be done by something like this:

esri.config.defaults.io.alwaysUseProxy = true;
esri.config.defaults.io.proxyUrl = "/proxy.php";

And then in proxy.php something like this; add the tile servers you need:

$serverUrls = array(
    array( 'url' => 'http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/', 'matchAll' => true, 'token' => '' ),
    array( 'url' => 'http://sampleserver2.arcgisonline.com/ArcGIS/rest/services/', 'matchAll' => true, 'token' => '' ),
    array( 'url' => 'http://tiles.arcgis.com/tiles/nSZVuSZjHpEZZbRo/arcgis/rest/services/',        'matchAll' => true, 'token' => '' ),
    array( 'url' => 'http://services.arcgis.com/nSZVuSZjHpEZZbRo/ArcGIS/rest/services/',        'matchAll' => true, 'token' => '' )
  );
0

One more possible option is to have a custom layer in your map, which calls the tiles directly from their HTTP End points, without passing through ArcGIS Server.

In our experience, we have found it to be orders of magnitude faster than using a proxy, especially, when there are many clients accessing the Web App. Additionally the CPU consumption on our Server was greatly reduced.

ESRI has provided a sample which shows how this can be done: Creating a custom tiled layer type

You just need to make sure that your url uses HTTPS and you are good to go.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.