CORS (Cross Origin Resource Sharing)

原文:https://developers.arcgis.com/javascript/latest/guide/cors/index.html

ArcGIS API for JavaScript 支持 CORS 。CORS 允许网络应用绕过浏览器的同源策略去访问其他服务器(域)的资源或服务。

当服务器和浏览器都支持 CORS 时,不需要使用代理(proxy)服务器来实现跨域请求。关于使用代理可查看:https://developers.arcgis.com/javascript/latest/guide/proxies/index.html

服务器必须预先配置为支持 CORS,浏览器必须有能力支持 CORS。所有现代浏览器都支持 CORS。

查看浏览器是否支持 CORS : https://caniuse.com/#feat=cors

关于服务器启用 CORS :https://enable-cors.org/

ArcGIS API for JavaScript 和 CORS

ArcGIS API for JavaScript 自动检测 CORS 支持。当加载服务时,它发送一个异步请求给 /rest/info 。

截图显示了请求和响应信息。请注意响应头信息 Access-Control-Allow-Origin 。它指定服务器支持 CORS,并且标准的 XMLHttpRequest 可以像访问同一个域一样访问服务器。

以下用例解释了如何在ArcGIS API for JavaScript Web应用程序中使用或不使用CORS支持。

示例:使用不支持 CORS 的服务器

截图是一个访问不支持 CORS 的服务器的请求响应信息。

因为服务器不支持 CORS,所以请求失败了,打印了错误信息到浏览器控制台。错误信息显示跨域请求不能被允许。

错误信息格式一般是这样的:

XMLHttpRequest cannot load {REQUESTED-URL}. No 'Access-Control-Allow-Origin' header on the requested resource. Origin '<APP-DOMAIN>' is therefore not allowed access.

在 ArcGIS 10.1 之前,CORS 是没有被启用的。

即便不支持 CORS,来自这个服务器的图层仍然能够显示。这是因为请求方式是 HTTP GET,响应格式是 JSONP。

JSONP 是一种在 URL 中指定回调函数的 JSON 响应。例如:

https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Population_World/MapServer?f=json&dpi=96&transparent=true&format=jpeg&callback=dojo.io.script.jsonp_dojoIoScript1._jsonpCallback

响应结果类似如下代码块:

 dojo.io.script.jsonp_dojoIoScript1._jsonpCallback({
    "currentVersion": 10.01,
    "serviceDescription": "This service contains population density polygons, country boundaries, and city locations for the world. The map is color coded based on the number of persons per square mile (per every 1.609 kilometers square). Population data sources included national population censuses, the United Nations demographic yearbooks, and others. In general, data currency ranged from 1981 to 1994. This is a sample service hosted by ESRI, powered by ArcGIS Server. ESRI has provided this example so that you may practice using ArcGIS APIs for JavaScript, Flex, and Silverlight. ESRI reserves the right to change or remove this service at any time and without notice.",
    "mapName": "Layers",
    "description": "This service contains population density polygons, country boundaries, and city locations for the world. The map is color coded based on the number of persons per square mile (per every 1.609 kilometers square). Population data sources included national population censuses, the United Nations demographic yearbooks, and others. In general, data currency ranged from 1981 to 1994.\n",
    "copyrightText": "(c) ESRI and its data partners",
    "layers": [{
        "id": 0,
        "name": "CEISEN Population",
        "parentLayerId": -1,
        "defaultVisibility": true,
        "subLayerIds": null,
        "minScale": 0,
        "maxScale": 0
    }],
    "tables": [],
    "spatialReference": {
        "wkid": 4326
    },
    "singleFusedMapCache": false,
    "initialExtent": {
        "xmin": -781.528595186209,
        "ymin": -399.851519127974,
        "xmax": 778.578125335329,
        "ymax": 423.455277935017,
        "spatialReference": {
            "wkid": 4326
        }
    },
    "fullExtent": {
        "xmin": -180,
        "ymin": -90,
        "xmax": 180,
        "ymax": 90,
        "spatialReference": {
            "wkid": 4326
        }
    },
    "units": "esriDecimalDegrees",
    "supportedImageFormatTypes": "PNG24,PNG,JPG,DIB,TIFF,EMF,PS,PDF,GIF,SVG,SVGZ,AI,BMP",
    "documentInfo": {
        "Title": "GlobalPopulation",
        "Author": "serverxadmin",
        "Comments": "",
        "Subject": "",
        "Category": "",
        "Keywords": "",
        "Credits": ""
    },
    "capabilities": "Map,Query,Data"
});

为了使用这种方法,API 需要一个HTTP GET 请求并返回 JavaScript 代码而不是标准的 JSON 数据。应用程序创建并将<script>标记插入到包含JSON数据的网页中,同时调用函数。

这种方式绕过了跨域安全问题,并允许访问服务。

这个错误是无害的,抑制它的一个方法是将 esriConfig.request 的 corsDection 属性设置为 false。

示例:API 不发送请求到 /rest/info

以下情况 API 不会向 /rest/info 发送请求:

  • API 有一个支持 CORS 的服务器名称列表。如果服务器已经包含在 esriConfig.request.corsEnabledServers 属性中,API 不会向 /rest/info 发送请求。
  • esriConfig.request.corsDection 属性被设置为 false。
  • 浏览器不支持 CORS。

示例:支持 CORS

当服务器支持 CORS 而程序没有意识到这一点,你可能会看到以下信息。

[esri.core.urlUtils] esri/config: esriConfig.request.proxyUrl is not set. If making a request to a CORS-enabled server, please push the domain into esriConfig.request.corsEnabledServers.

为了解决这个问题,需要添加服务器的域名到 esri.config.defaults.io.corsEnabledServers

require(["esri/config"], function(esriConfig) {
  esriConfig.request.corsEnabledServers.push("www.example.com");
});

以上代码会用在 ArcGIS Server 和第三方服务上。

API 默认配置了一些支持 CORS 的服务器,这些服务器 API 将会自动识别。默认配置的服务器列表:https://developers.arcgis.com/javascript/latest/api-reference/esri-config.html#request

如果不知道服务器是否支持 CORS ,可访问:http://test-cors.org/

其他情况

例如,可能有服务器上没有启用CORS并且JSONP也不被支持,或者服务在防火墙之后。这种情况需要使用 proxy page。

results matching ""

    No results matching ""