ArcGIS Server与JavaScript API部署中的CORS跨域解决方案
内网部署的地图服务预览问题
在内网环境中部署ArcGIS Server后,地图服务可能无法正常预览。这是因为预览功能默认会调用在线ArcGIS.com服务,而内网环境无法访问外部资源。
解决方案是在IIS中部署与ArcGIS Server版本匹配的ArcGIS JavaScript API。例如ArcGIS Server 10.2.2需要使用JavaScript API 3.7版本,4.18版本在此场景下不适用。
服务器端CORS配置
需要在ArcGIS Server管理界面配置CORS路径:
访问地址:http://localhost:6080/arcgis/admin/login
配置路径:http://localhost:6080/arcgis/admin/system/handlers/rest/servicesdirectory
配置修改后需要重启ArcGIS Server服务,某些情况下需要重启整个系统才能使配置生效。
多版本JavaScript API部署
在IIS中部署两个版本的JavaScript API:
- 版本3.7用于服务预览
- 版本4.18用于前端应用开发
两个版本都需要配置跨域支持。修改init.js和dojo.js中的路径指向物理目录,通常将IIS指向4.18版本目录。
IIS跨域配置
在JavaScript API目录下部署web.config文件,配置CORS跨域:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<staticContent>
<remove fileExtension=".woff" />
<mimeMap fileExtension=".woff" mimeType="font/x-font-woff" />
</staticContent>
<directoryBrowse enabled="true" />
<defaultDocument>
<files>
<add value="dojo.js" />
</files>
</defaultDocument>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Methods" value="OPTIONS,POST,GET" />
<add name="Access-Control-Allow-Headers" value="x-requested-with,content-type" />
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
浏览器缓存清理
Chrome浏览器需要清除缓存,否则可能持续出现CORS错误。
测试示例
创建测试页面验证配置:
<html>
<head>
<meta charset="utf-8" />
<meta name="referrer" content="no-referrer"/>
<title>ArcGIS地图显示测试</title>
<style>
html, body, #mapContainer {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<link rel="stylesheet" href="http://192.168.28.72:8081/esri/themes/light/main.css">
<script src="http://192.168.28.72:8081/init.js"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/FeatureLayer",
"esri/widgets/LayerList"
], function(Map, MapView, FeatureLayer, LayerList) {
const polygonLayer = new FeatureLayer("http://192.168.28.72:6080/arcgis/rest/services/shihezi/esti/MapServer/33", {
mode: FeatureLayer.MODE_SNAPSHOT,
outFields: ["*"]
});
const baseMap = new Map({});
baseMap.add(polygonLayer);
const mapView = new MapView({
map: baseMap,
container: "mapContainer",
scale: 50000,
zoom: 12,
center: [86.092, 44.313]
});
mapView.when(function() {
var layerPanel = new LayerList({
view: mapView
});
mapView.ui.add(layerPanel, "top-right");
});
});
</script>
</head>
<body>
<div id="mapContainer"></div>
</body>
</html>
