图层里的权限验证
群里有好多同学问:如何给图层配置权限认证参数,比如token
,类似如下的效果:
因为有太多的同学问了,故这里专门写篇文章来讨论下这个问题.
根本原因
目前同学问的问题都是:如何给图层配置headers
参数来进行权限验证。
我发现根本原因是后端只支持headers
验证的导致的,然后导致群友来问这个问题,所以问题的根源是后端导致的
为啥这么说?
- 前端请求可不是仅仅有
ajax/fetch
这种方式 - 还有一些其他的静态请求,比如图片,模型,视屏,图标,下载地址这些,如果也需要权限验证,如果只支持
headers
验证这种就会出现问题了 - 比如这种静态图片的也需要权限验证,这时怎么办呢? 拦截图片地址进行fetch请求,然后把图片格式化成
Base64
来脱裤子放屁?
html
<img src="https://example.com/a.png" />
- 有些地图引擎加载瓦片资源用的就是
Image
标签,比如leafletjs
,这时又该怎么办?重写图层瓦片请求方法来 拦截瓦片地址进行fetch请求,然后把图片格式化成Base64
来脱裤子放屁?
解决问题的根本方法
后端支持token的参数(get/post等方法的参数)和heasers两种方式验证即可,具体表现在:
- 后端从参数里拿token值,拿不到再从
headers
里拿 - 前端可以把
token
放到参数(query/body)里或者headers
里 - 至于前端究竟把
token
放到哪里,有前端需求决定,比如图层这种验证,最简单的方法就是https://example.com?token=xxx
这种方式 - 具体的可以参考天地图,高德,百度等都是直接
get
传参的
maptalks里图层传递权限验证参数
WARNING
这里再次强调,如果你的后端配合的话请按照上面我说的权限验证的方式进行改造,最简单的方法就是https://example.com?token=xxx
这种方式
maptalks里常见的图层需要权限验证的图层有:TileLayer
,VectorTileLayer
这两个图层都提供了fetchOptions
参数来让你配置fetch请求时的一些参数
js
const fetchOptions = {
//referer: "https://services.arcgisonline.com",
headers: {
token: "your token",
//others params
},
//other config
};
- TileLayer
js
const tileLayer = new maptalks.TileLayer("base", {
urlTemplate: "./../assets/data/tile-image/{z}/{x}/{y}.png",
subdomains: ["a", "b", "c"],
maxAvailableZoom: 18,
decodeImageInWorker: true,
fetchOptions,
});
WARNING
TileLayer 默认请求用的Image
标签的,所以需要你开启fetch请求参数decodeImageInWorker
,这样就可以利用fetch
的headers
了
- VectorTileLayer
js
const layer = new maptalks.VectorTileLayer("geo", {
fetchOptions,
version: 1,
urlTemplate: "./../assets/data/vt-test/{z}/{x}/{y}.pbf",
});
WARNING
VectorTileLayer 数据请求本来就是fetch
的,所以直接配置fetchOptions
即可
完全自定义
TileLayer
,VectorTileLayer
也提供了完全自定义的方法,让用户完全掌控瓦片的请求和控制
- TileLayer 提供了 loadTileBitmap 方法可以让我们自定义瓦片请求
js
const baseLayer = new maptalks.TileLayer("base", {
urlTemplate:
"https://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}",
subdomains: ["a", "b", "c", "d"],
maxAvailableZoom: 18,
version: 1,
});
baseLayer.on("renderercreate", function (e) {
//load tile image
// img(Image): an Image object
// url(String): the url of the tile
e.renderer.loadTileBitmap = function (url, tile, callback, options) {
console.log(options.command);
};
});
- VectorTileLayer 提供了 loadTileArrayBuffer 方法可以让我们自定义瓦片请求
js
const layer = new maptalks.VectorTileLayer("geo", {
// features: true,
// pickGeometry: true,
version: 1,
urlTemplate: "./../assets/data/vt-test/{z}/{x}/{y}.pbf",
});
layer.on("renderercreate", function (e) {
//load tile image
// img(Image): an Image object
// url(String): the url of the tile
e.renderer.loadTileArrayBuffer = function (url, tile, callback, options) {
console.log(options.command);
};
});
TIP
你可以在对应的方法里做任何操作,数据请求,数据转化等,甚至可以利用一些常用的网络请求库 axios
啥的,请求好的数据 进行callback
即可.
甚至可以进行本地缓存来缓存图层的数据啥的利用IndexedDB缓存图层数据