Select to view content in your preferred language

Undesirable functionality: WMSLayer doesn't use original url in GetMap (and other requests)

182
4
Jump to solution
a week ago
D_R_
by
New Contributor II

Good afternoon,

I have same problem somebody in this topic -> https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/jsapi-4-requesting-wrong-url-when... had.

I create a simple WMSLayer({url: url}) and under the hood SDK replaces that url with some other url which is retrieved from WMS's GetCapabilities.

ArcGIS API for JavaScript (legacy) 3.X didn't have this problem. I see this new functionality as a regression..

What are your thoughts about it? Any plans to improve WMS constructor?

Theoretically I can use esriConfig.request.interceptors and change url in "before" method, but the problem is that you have to hardcode url you need to replace. I mean just look at https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/jsapi-4-requesting-wrong-url-when... -> It is bad practice to hardcode host and url as was done in that case... And in my case I have big amount of WMS layers...

Could you improve your SDK by adding interceptor to layer's constructor maybe so that it acts on current layer only?? I think that should help in such cases..

 

Tags (1)
0 Kudos
1 Solution

Accepted Solutions
JoelBennett
MVP Regular Contributor

Ok, there's actually a significant difference between what's going on in this case versus what was going on in the other thread.  Before getting into the difference, just a brief description of things you may already know (for the sake of clarity).  When creating a WMSLayer, the layer sends a GetCapabilities request to get information about the service it will be accessing.  The response is an XML document, and embedded within is the URLs the application should use when making calls to GetMap and/or GetFeatureInfo.

In the case of the other thread, the URL for GetMap was a relative URL.  Since the hostname was not included, the SDK likely assumed it was the same host as the URL in the browser's address bar.  Since the host for the page in the browser was not the same as the host for the WMS server, this gave the unexpected results described in that thread.  Personally, I think the SDK should be able to handle relative URLs better, using the hostname passed into the constructor instead, but those kinds of design decisions are the SDK development team's prerogative.

However, this is not what's happening in your case.  Instead, the GetCapabilities response has absolute URLs, and the GetMap URL is the hard-coded value "http://46.255.211.67:85/geoserver/Etnografinis_zemelapis/ows?SERVICE=WMS&".  Therefore, the SDK is working exactly as it should by sending the GetMap requests to that URL, because that's what the service told it to do.

There's really only two ways to deal with this.  (1) Contact the WMS service's administrator, and request that they reconfigure the service.  It seems unlikely to me that's going to work though.  Instead (2) you will have to do some replacing on the client-side...there's just no way around it.  You could use a RequestInterceptor like the other thread shows, or you could fix the URLs on your layer object by doing something like the following:

 

const layer = new WMSLayer({
  url: "https://www.geoportal.lt/mapproxy/etnografinis_zemelapis/wms"
});

layer.load().then(() => {
  layer.featureInfoUrl = layer.featureInfoUrl.replace("http://46.255.211.67:85/geoserver/", "https://www.geoportal.lt/mapproxy/");
  layer.mapUrl = layer.mapUrl.replace("http://46.255.211.67:85/geoserver/", "https://www.geoportal.lt/mapproxy/");
});

 

 

View solution in original post

0 Kudos
4 Replies
JoelBennett
MVP Regular Contributor

Can you specify the value you're using for the url property?  The example given in the thread you referred to doesn't appear to be reachable anymore, at least for me.

0 Kudos
D_R_
by
New Contributor II

Thank you for your willingness to help.

You can use this one:

https://www.geoportal.lt/mapproxy/etnografinis_zemelapis/wms?SERVICE=WMS&REQUEST=GetCapabilities

In WMSLayer (ArcGIS Maps SDK for JavaScript constructor) url is internally changed to http://46.255.211.67:85/geoserver/Etnografinis_zemelapis/ows and it is very undesirable in our case. It destroys all our logic to use our internal proxy service..

ArcGIS API for JavaScript (legacy) didn't have this problem.

0 Kudos
JoelBennett
MVP Regular Contributor

Ok, there's actually a significant difference between what's going on in this case versus what was going on in the other thread.  Before getting into the difference, just a brief description of things you may already know (for the sake of clarity).  When creating a WMSLayer, the layer sends a GetCapabilities request to get information about the service it will be accessing.  The response is an XML document, and embedded within is the URLs the application should use when making calls to GetMap and/or GetFeatureInfo.

In the case of the other thread, the URL for GetMap was a relative URL.  Since the hostname was not included, the SDK likely assumed it was the same host as the URL in the browser's address bar.  Since the host for the page in the browser was not the same as the host for the WMS server, this gave the unexpected results described in that thread.  Personally, I think the SDK should be able to handle relative URLs better, using the hostname passed into the constructor instead, but those kinds of design decisions are the SDK development team's prerogative.

However, this is not what's happening in your case.  Instead, the GetCapabilities response has absolute URLs, and the GetMap URL is the hard-coded value "http://46.255.211.67:85/geoserver/Etnografinis_zemelapis/ows?SERVICE=WMS&".  Therefore, the SDK is working exactly as it should by sending the GetMap requests to that URL, because that's what the service told it to do.

There's really only two ways to deal with this.  (1) Contact the WMS service's administrator, and request that they reconfigure the service.  It seems unlikely to me that's going to work though.  Instead (2) you will have to do some replacing on the client-side...there's just no way around it.  You could use a RequestInterceptor like the other thread shows, or you could fix the URLs on your layer object by doing something like the following:

 

const layer = new WMSLayer({
  url: "https://www.geoportal.lt/mapproxy/etnografinis_zemelapis/wms"
});

layer.load().then(() => {
  layer.featureInfoUrl = layer.featureInfoUrl.replace("http://46.255.211.67:85/geoserver/", "https://www.geoportal.lt/mapproxy/");
  layer.mapUrl = layer.mapUrl.replace("http://46.255.211.67:85/geoserver/", "https://www.geoportal.lt/mapproxy/");
});

 

 

0 Kudos
D_R_
by
New Contributor II

Thank you for taking your time to write a detailed response! Yeah, my case and the other one differ a bit but very similar solution was needed. My wording "same problem" was not 100% correct there 🙂 

I didn't see mapUrl property in WMSLayer API reference (https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-WMSLayer.html) so it must be an internal one but it looks promising 🤞

0 Kudos