【问题标题】:Mapbox GL: How can I handle invalid/expired access tokens?Mapbox GL:如何处理无效/过期的访问令牌?
【发布时间】:2023-02-17 05:16:47
【问题描述】:

我已经实现了 Mapbox GL:

script.src = 'https://api.mapbox.com/mapbox-gl-js/v2.8.2/mapbox-gl.js';
script.onload = function() {
    mapboxgl.accessToken = 'invalid_token';
    map = new mapboxgl.Map({
        container: 'mapsection', // container ID
        style: 'mapbox://styles/mapbox/streets-v11' // style URL
    });
}

如果访问令牌无效或过期,那么控制台中会显示一条消息,但我该如何在我的代码中处理这个问题? try .. catchmap.on('error') 都试过了,但都不承认有错误。地图上的任何操作都没有错误地执行,但页面上什么也看不到。

或者,是否有 API 来验证给定的令牌?

【问题讨论】:

    标签: mapbox mapbox-gl-js mapbox-gl


    【解决方案1】:

    我不确定,但如果您获取正在请求的 URL 之一(通过查看开发人员工具),并使用 fetch 查询该 URL,您可能会返回 200 以获得正确的令牌,或 401403 无效令牌(或其他问题)。

    【讨论】:

    • 有趣的方法。 Mapbox GL 代码执行对 api.mapbox.com/styles/v1/mapbox/… 的请求,它返回 401。我可以手动检查这个地址,尽管该地址将来可能会更改。
    • 该地址极不可能更改。
    • 我会说地址可能会改变;看到 URL 的 v1 部分了吗?如果有更新,它将不再是v1...
    • 实际上恰恰相反。这就是向您保证它不会改变的原因。他们可能会在某个时候引入 v2,但很可能会保留 v1 很长时间。
    【解决方案2】:

    看起来我快到了,只是犯了一个小错误。它确实是我需要使用的 map.on('error') 事件处理程序:

    script.src = 'https://api.mapbox.com/mapbox-gl-js/v2.8.2/mapbox-gl.js';
    script.onload = function() {
        mapboxgl.accessToken = 'invalid_token';
        map = new mapboxgl.Map({
            container: 'mapsection', // container ID
            style: 'mapbox://styles/mapbox/streets-v11' // style URL
        });
        map.on('error', (response) => {
            alert(response.error.message)
        });
    }
    

    【讨论】:

      【解决方案3】:

      即使 Mapbox 访问令牌无效,使用 map.on('error') 也会导致 Mapbox GL (v2.12.0) 创建完整的 HTML DIV 结构。

      <div id="map-container" class="mapboxgl-map"><div class="mapboxgl-canary" style="visibility: hidden;"></div><div class="mapboxgl-canvas-container mapboxgl-interactive mapboxgl-touch-drag-pan mapboxgl-touch-zoom-rotate"><canvas class="mapboxgl-canvas" tabindex="0" aria-label="Map" role="region" width="780" height="724" style="width: 519.115px; height: 482.542px;"></canvas></div><div class="mapboxgl-control-container"><div class="mapboxgl-ctrl-top-left"></div><div class="mapboxgl-ctrl-top-right"><div class="mapboxgl-ctrl mapboxgl-ctrl-group"><button class="mapboxgl-ctrl-zoom-in" type="button" aria-label="Zoom in" aria-disabled="false"><span class="mapboxgl-ctrl-icon" aria-hidden="true" title="Zoom in"></span></button><button class="mapboxgl-ctrl-zoom-out" type="button" aria-label="Zoom out" aria-disabled="false"><span class="mapboxgl-ctrl-icon" aria-hidden="true" title="Zoom out"></span></button><button class="mapboxgl-ctrl-compass" type="button" aria-label="Reset bearing to north"><span class="mapboxgl-ctrl-icon" aria-hidden="true" title="Reset bearing to north" style="transform: rotate(0deg);"></span></button></div></div><div class="mapboxgl-ctrl-bottom-left"><div class="mapboxgl-ctrl" style="display: block;"><a class="mapboxgl-ctrl-logo" target="_blank" rel="noopener nofollow" href="https://www.mapbox.com/" aria-label="Mapbox logo"></a></div></div><div class="mapboxgl-ctrl-bottom-right"></div></div></div>
      

      为了避免 mapbox-gl.js 执行不必要的代码,我使用了 @Steve 的建议,即使用 fetch 查询到 Mapbox API。当访问令牌有效时,对地图样式 API URL 的请求会产生约 70KB 的响应。对 Mapbox 地理编码 API(版本 5 较旧;v6 是截至 2023 年 2 月的最新版本)的请求,使用不存在的位置作为搜索字符串会产生 343 字节的响应。

      const url = `https://api.mapbox.com/geocoding/v5/mapbox.places/rndstrasdf.json?access_token=${mapboxAccessToken}`;
      

      然而,这一切似乎都是不必要的,因为如果 Mapbox 在执行任何 mapbox-gl 之前提供访问令牌验证 API 的效率会更高,就像他们提供 mapbox-gl-supported plugin 一样。

      出于性能原因,最好检查 Mapbox GL JS 是 在加载脚本的麻烦之前支持 初始化页面上的地图。

      document.addEventListener('DOMContentLoaded', function() {
        loadMap()
          .then(map => console.log("Map loaded successfully into element with ID: " + map._container.id))
          .catch(error => console.error("Map load failed with the error: " + error.message));
      });
      
      function loadMap() {
        return new Promise((resolve, reject) => {
      
          const mapboxAccessToken = "ADD_YOUR_VALID_OR_INVALID_ACCESS_TOKEN";
      
          // Using the following URL in a 'fetch' API results in a ~70KB response.
          //const url = `https://api.mapbox.com/styles/v1/mapbox/streets-v11?access_token=${mapboxAccessToken}`;
          //const url = `https://api.mapbox.com/styles/v1/mapbox/streets-v11?access_token=invalid`;
      
          // A URL to Mapbox geocoding to validate a Mapbox access token
          // results in a 343 byte response using a non-existent place name.
          // Place search at https://www.mapbox.com/geocoding
          // Temporary Geocoding API pricing https://www.mapbox.com/pricing#search
          // A valid place name -> "Los Angeles"
          //const url = `https://api.mapbox.com/geocoding/v5/mapbox.places/Los Angeles.json?access_token=${mapboxAccessToken}`;
          const url = `https://api.mapbox.com/geocoding/v5/mapbox.places/rndstrasdf.json?access_token=${mapboxAccessToken}`;
      
          fetch(url)
            .then(response => {
              if (!response.ok) {
                response.message = "Connected to Mapbox service but with an invalid access token.";
                reject(response);
                return;
              }
      
              // Request succeeded. Response is an empty GeoJSON 'features' collection
              // 343 bytes
              /*
               '{"type":"FeatureCollection","query":["rndstrasdf"],"features":[],
               "attribution":"NOTICE: © 2023 Mapbox and its suppliers. All rights reserved. 
               Use of this data is subject to the Mapbox Terms of Service 
               (https://www.mapbox.com/about/maps/). This response and the information
               it contains may not be retained. POI(s) provided by Foursquare."}'
               */
              response.text().then(text => {
                console.log(text);
              });
      
              mapboxgl.accessToken = mapboxAccessToken;
      
              // stackoverflow.com/questions/72254578/how-to-solve-that-a-valid-mapbox-access-token-is-required-to-use-mapbox-gl-js
              // github.com/mapbox/mapbox-gl-js/releases/tag/v2.0.0
              // "Beginning with v2.0.0, a billable map load occurs whenever a
              // Map object is initialized. Before updating an existing
              // implementation from v1.x.x to v2.x.x, please review the
              // pricing documentation to estimate expected costs."
      
              const map = new mapboxgl.Map({
                container: "map-container",
                style: 'mapbox://styles/mapbox/streets-v11',
                center: [12.79690, 47.32350], // Longitude, latitude
                zoom: 5
              });
      
              // Add zoom and rotation controls to the map
              // docs.mapbox.com/mapbox-gl-js/example/navigation
              map.addControl(new mapboxgl.NavigationControl());
      
              map.on('load', () => resolve(map));
              map.on('error', error => reject(error));
            })
            .catch(error => {
              reject(error);
            });
        });
      }
      <link href='https://api.mapbox.com/mapbox-gl-js/v2.12.0/mapbox-gl.css' rel='stylesheet' />
      <script src='https://api.mapbox.com/mapbox-gl-js/v2.12.0/mapbox-gl.js'></script>
      <div id="map-container" style="width: 100%; height: 80vh;"></div>

      【讨论】:

        猜你喜欢
        • 2019-12-06
        • 1970-01-01
        • 2016-01-14
        • 2017-12-03
        • 2022-06-27
        • 2012-10-05
        • 2015-04-23
        • 2014-10-06
        • 1970-01-01
        相关资源
        最近更新 更多