1- // Main application logic
2-
3- const CORS_PROXY = 'https://corsproxy.io/?' ;
1+ // Main application logic (CORS proxy removed - now using file upload for blocked resources)
42
53// Format dimension name as WMS parameter (time/elevation unchanged, others get DIM_ prefix)
64function formatDimensionParam ( dimensionName ) {
@@ -127,11 +125,12 @@ function parseISO8601Interval(intervalString) {
127125
128126const wmsUrlInput = document . getElementById ( 'wms-url' ) ;
129127const loadBtn = document . getElementById ( 'load-btn' ) ;
128+ const loadFileBtn = document . getElementById ( 'load-file-btn' ) ;
129+ const fileInput = document . getElementById ( 'file-input' ) ;
130130const serviceInfo = document . getElementById ( 'service-info' ) ;
131131const serviceDetails = document . getElementById ( 'service-details' ) ;
132132
133133let currentWmsBaseUrl = '' ;
134- let currentUsedProxy = false ;
135134
136135// Load capabilities URLs from file on page load
137136async function loadCapabilitiesPresets ( ) {
@@ -182,20 +181,57 @@ loadBtn.addEventListener('click', async () => {
182181 try {
183182 loadBtn . disabled = true ;
184183 loadBtn . textContent = 'Loading...' ;
184+ // Hide file upload button in case it was shown from a previous attempt
185+ loadFileBtn . style . display = 'none' ;
185186
186187 await loadWMSCapabilities ( url ) ;
187188
188189 // Clear input after successful load
189190 wmsUrlInput . value = '' ;
190191 } catch ( error ) {
191192 console . error ( 'Error loading WMS capabilities:' , error ) ;
192- alert ( 'Failed to load WMS capabilities. Check console for details.' ) ;
193+
194+ // Check if it's a CORS error (typical fetch failures are TypeError)
195+ if ( error . name === 'TypeError' && error . message . includes ( 'fetch' ) ) {
196+ alert ( 'Failed to load WMS capabilities due to CORS restrictions.\n\nPlease download the capabilities file in another tab and use "Load from File" button.' ) ;
197+ loadFileBtn . style . display = 'inline-block' ;
198+ } else {
199+ alert ( 'Failed to load WMS capabilities. Check console for details.' ) ;
200+ }
193201 } finally {
194202 loadBtn . disabled = false ;
195203 loadBtn . textContent = 'Load Service' ;
196204 }
197205} ) ;
198206
207+ loadFileBtn . addEventListener ( 'click' , ( ) => {
208+ fileInput . click ( ) ;
209+ } ) ;
210+
211+ fileInput . addEventListener ( 'change' , async ( event ) => {
212+ const file = event . target . files [ 0 ] ;
213+ if ( ! file ) return ;
214+
215+ try {
216+ loadFileBtn . disabled = true ;
217+ loadFileBtn . textContent = 'Processing...' ;
218+
219+ const text = await file . text ( ) ;
220+ await processCapabilitiesXML ( text , 'file' ) ;
221+
222+ // Clear file input and hide button after successful load
223+ fileInput . value = '' ;
224+ loadFileBtn . style . display = 'none' ;
225+ wmsUrlInput . value = '' ;
226+ } catch ( error ) {
227+ console . error ( 'Error processing capabilities file:' , error ) ;
228+ alert ( 'Failed to process capabilities file. Check console for details.' ) ;
229+ } finally {
230+ loadFileBtn . disabled = false ;
231+ loadFileBtn . textContent = 'Load from File' ;
232+ }
233+ } ) ;
234+
199235function detectServiceType ( xmlDoc ) {
200236 const rootElement = xmlDoc . documentElement ;
201237 const rootName = rootElement . localName || rootElement . nodeName ;
@@ -211,45 +247,52 @@ function detectServiceType(xmlDoc) {
211247}
212248
213249async function loadWMSCapabilities ( url ) {
214- let response ;
215- let usedProxy = false ;
216-
217- try {
218- // Try direct fetch first
219- response = await fetch ( url ) ;
220- } catch ( error ) {
221- // If direct fetch fails (likely CORS), try with proxy
222- const proxyUrl = CORS_PROXY + encodeURIComponent ( url ) ;
223- console . log ( 'Direct fetch failed, trying CORS proxy...' ) ;
224- console . log ( 'Proxy URL:' , proxyUrl ) ;
225- usedProxy = true ;
226- response = await fetch ( proxyUrl ) ;
227- }
228-
250+ // Try direct fetch only - no CORS proxy
251+ const response = await fetch ( url ) ;
229252 const text = await response . text ( ) ;
253+
254+ await processCapabilitiesXML ( text , url ) ;
255+ }
230256
257+ async function processCapabilitiesXML ( xmlText , source ) {
231258 // Parse XML
232259 const parser = new DOMParser ( ) ;
233- const xmlDoc = parser . parseFromString ( text , 'text/xml' ) ;
260+ const xmlDoc = parser . parseFromString ( xmlText , 'text/xml' ) ;
261+
262+ // Check for parsing errors
263+ const parseError = xmlDoc . querySelector ( 'parsererror' ) ;
264+ if ( parseError ) {
265+ throw new Error ( 'XML parsing error: ' + parseError . textContent ) ;
266+ }
234267
235268 // Detect service type
236269 const serviceType = detectServiceType ( xmlDoc ) ;
237270 console . log ( 'Detected service type:' , serviceType ) ;
238271
239- // Store base URL and proxy flag
240- currentWmsBaseUrl = url . split ( '?' ) [ 0 ] ;
241- currentUsedProxy = usedProxy ;
272+ // Store base URL (extract from URL if it's a URL, otherwise use empty string for file uploads)
273+ if ( source !== 'file' && typeof source === 'string' ) {
274+ currentWmsBaseUrl = source . split ( '?' ) [ 0 ] ;
275+ } else {
276+ // For file uploads, try to extract from XML or use empty string
277+ const onlineResource = xmlDoc . querySelector ( 'Capability Request GetMap DCPType HTTP Get OnlineResource' ) ;
278+ if ( onlineResource ) {
279+ const href = onlineResource . getAttribute ( 'xlink:href' ) || onlineResource . getAttribute ( 'href' ) ;
280+ if ( href ) {
281+ currentWmsBaseUrl = href . split ( '?' ) [ 0 ] ;
282+ }
283+ }
284+ }
242285
243286 if ( serviceType === 'WMTS' ) {
244287 // Extract WMTS service information
245288 const serviceInfo = extractWMTSInfo ( xmlDoc , currentWmsBaseUrl ) ;
246289 // Display WMTS service information
247- displayWMTSInfo ( serviceInfo , usedProxy ? 'proxy ' : 'direct' , url ) ;
290+ displayWMTSInfo ( serviceInfo , source === 'file' ? 'file ' : 'direct' , source === 'file' ? 'file' : source ) ;
248291 } else {
249292 // Extract WMS service information
250293 const serviceInfo = extractServiceInfo ( xmlDoc , currentWmsBaseUrl ) ;
251294 // Display WMS service information
252- displayServiceInfo ( serviceInfo , usedProxy , url ) ;
295+ displayServiceInfo ( serviceInfo , source === 'file' ? 'file' : 'direct' , source === 'file' ? 'file' : source ) ;
253296 }
254297}
255298
@@ -848,9 +891,9 @@ function displayWMTSInfo(info, source, url) {
848891 } ) ;
849892}
850893
851- function displayServiceInfo ( info , usedProxy , loadedUrl ) {
852- const proxyNote = usedProxy
853- ? '<p><em>(Loaded via CORS proxy )</em></p>'
894+ function displayServiceInfo ( info , source , loadedUrl ) {
895+ const sourceNote = source === 'file'
896+ ? '<p><em>(Loaded from file )</em></p>'
854897 : '' ;
855898
856899 const formatOptions = info . getFeatureInfoFormats . map ( fmt =>
@@ -923,7 +966,7 @@ function displayServiceInfo(info, usedProxy, loadedUrl) {
923966 </div>
924967 <div class="layer-viewer-container" id="viewer-container-${ index } ">
925968 <img
926- src="${ buildGetMapUrl ( info . baseUrl , layer , info . version , usedProxy , layer . styles && layer . styles . length > 0 ? layer . styles [ 0 ] . name : '' ) } "
969+ src="${ buildGetMapUrl ( info . baseUrl , layer , info . version , layer . styles && layer . styles . length > 0 ? layer . styles [ 0 ] . name : '' ) } "
927970 alt="Preview of ${ layer . title } "
928971 class="layer-preview"
929972 id="preview-${ index } "
@@ -935,14 +978,14 @@ function displayServiceInfo(info, usedProxy, loadedUrl) {
935978 . join ( '' ) ;
936979
937980 serviceDetails . innerHTML = `
981+ ${ sourceNote }
938982 <p><strong>Title:</strong> ${ info . title } </p>
939983 <p><strong>Version:</strong> ${ info . version } </p>
940984 <details class="service-abstract">
941985 <summary><strong>Abstract</strong></summary>
942986 <p>${ info . abstract } </p>
943987 </details>
944- <p><strong>Loaded URL:</strong> <a href="${ loadedUrl } " target="_blank" rel="noopener noreferrer">${ loadedUrl } </a></p>
945- ${ proxyNote }
988+ ${ source !== 'file' ? `<p><strong>Loaded URL:</strong> <a href="${ loadedUrl } " target="_blank" rel="noopener noreferrer">${ loadedUrl } </a></p>` : '' }
946989 <h3>Available Layers</h3>
947990 <div class="layers-list">
948991 ${ layersList }
@@ -1034,7 +1077,7 @@ function displayServiceInfo(info, usedProxy, loadedUrl) {
10341077 // Update thumbnail
10351078 const preview = document . getElementById ( `preview-${ index } ` ) ;
10361079 if ( preview ) {
1037- preview . src = buildGetMapUrl ( info . baseUrl , layer , info . version , usedProxy , e . target . value ) ;
1080+ preview . src = buildGetMapUrl ( info . baseUrl , layer , info . version , e . target . value ) ;
10381081 }
10391082
10401083 // Update viewer if it's checked
@@ -1164,7 +1207,7 @@ function displayServiceInfo(info, usedProxy, loadedUrl) {
11641207 } ) ;
11651208}
11661209
1167- function buildGetMapUrl ( baseUrl , layer , version , usedProxy , styleName ) {
1210+ function buildGetMapUrl ( baseUrl , layer , version , styleName ) {
11681211 const { bbox } = layer ;
11691212 const params = new URLSearchParams ( {
11701213 SERVICE : 'WMS' ,
0 commit comments