Skip to content
目录

图层里的权限验证

群里有好多同学问:如何给图层配置权限认证参数,比如token,类似如下的效果:

M~C)HQF%7DM_ZDIK%40WAK1WEFY.png

因为有太多的同学问了,故这里专门写篇文章来讨论下这个问题.

根本原因

目前同学问的问题都是:如何给图层配置headers参数来进行权限验证。

我发现根本原因是后端只支持headers验证的导致的,然后导致群友来问这个问题,所以问题的根源是后端导致的

为啥这么说?

  • 前端请求可不是仅仅有ajax/fetch这种方式
  • 还有一些其他的静态请求,比如图片,模型,视屏,图标,下载地址这些,如果也需要权限验证,如果只支持headers验证这种就会出现问题了
  • 比如这种静态图片的也需要权限验证,这时怎么办呢? 拦截图片地址进行fetch请求,然后把图片格式化成 Base64来脱裤子放屁?
html
<img src="https://example.com/a.png" />
  • 有些地图引擎加载瓦片资源用的就是 Image标签,比如leafletjs,这时又该怎么办?重写图层瓦片请求方法来 拦截瓦片地址进行fetch请求,然后把图片格式化成 Base64来脱裤子放屁?

DW%7BTZRTFSR2E5B_OKFP~B8V.png

解决问题的根本方法

后端支持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请求时的一些参数

layer carry header token demo

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,这样就可以利用fetchheaders

  • 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缓存图层数据

maptalks教程 document auto generated by mdpress and vitepress