You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenLayers集成英国地形测量局(UKOS)地图时,OAuth2令牌异步获取的返回值等待问题求助

解决OpenLayers中UKOS地图OAuth2令牌异步获取的问题

你的核心问题在于**UKOS.getToken()是异步函数,它返回的是一个Promise对象,而非直接的令牌字符串**,直接把它拼在Authorization头里会导致请求头带上的是"Bearer [object Promise]",而不是实际的令牌值——这就是为什么你会先拿到undefined、触发错误,之后console.log又能打印出正确令牌:因为Promise是后续才resolve的,但此时WMTS请求已经提前发出去了。

下面是两种可行的解决方案:

方案一:用async/await包裹WMTS请求逻辑

把你的WMTS请求代码放在一个async函数里,等待令牌获取完成后再执行请求:

async function loadUKOSMap() {
  try {
    // 等待令牌获取完成,拿到实际的令牌字符串
    const accessToken = await UKOS.getToken();
    
    // 发起WMTS GetCapabilities请求
    const response = await fetch(UKOS.WMTS + "&request=GetCapabilities&version=2.0.0", {
      headers: {
        Authorization: `Bearer ${accessToken}`
      },
    });

    if (!response.ok) {
      throw new Error(`WMTS请求失败: ${response.status}`);
    }

    // 后续处理,比如解析WMTS能力文档、初始化OpenLayers图层等
    const capabilities = await response.text();
    // ... 你的地图初始化逻辑
  } catch (error) {
    console.error('地图加载出错:', error);
    // 这里可以添加页面错误提示逻辑
  }
}

// 调用初始化函数启动流程
loadUKOSMap();

方案二:用Promise链式调用(兼容旧环境)

如果需要兼容像IE这类不支持async/await的浏览器,可以用Promise的链式调用:

UKOS.getToken()
  .then(accessToken => {
    // 令牌获取成功后,发起WMTS请求
    return fetch(UKOS.WMTS + "&request=GetCapabilities&version=2.0.0", {
      headers: {
        Authorization: `Bearer ${accessToken}`
      },
    });
  })
  .then(response => {
    if (!response.ok) {
      throw new Error(`WMTS请求失败: ${response.status}`);
    }
    return response.text();
  })
  .then(capabilities => {
    // 处理WMTS能力文档,初始化地图图层
  })
  .catch(error => {
    console.error('地图加载出错:', error);
  });

额外优化:完善令牌获取的错误处理

为了避免令牌获取失败导致后续逻辑异常,建议给UKOS.getToken()添加错误捕获:

UKOS.getToken = async function () { 
  // 检查令牌是否有效或即将过期
  if (!UKOS.token || new Date().getTime() > UKOS.token.issued_at + 1000 * (UKOS.token.expires_in - 15)) {
    try {
      const response = await fetch(/* CGI Script地址 */);
      if (!response.ok) {
        throw new Error(`令牌请求失败,状态码: ${response.status}`);
      }
      UKOS.token = await response.json();
    } catch (err) {
      console.error('获取UKOS令牌出错:', err);
      throw err; // 抛出错误,让调用方统一处理
    }
  }
  console.log(UKOS.token.access_token); 
  return UKOS.token.access_token; 
};

为什么之前的代码不生效?

  • 当你直接在fetch的headers里写Authorization: "Bearer " + UKOS.getToken()时,UKOS.getToken()返回的是Promise对象,此时会被强制转成字符串"[object Promise]",而非实际的令牌值。
  • 即使你在getToken里用了await,也必须在async函数中使用await才能拿到实际值,否则await会被忽略,直接返回Promise。

内容的提问来源于stack exchange,提问作者CharlesMacfarlane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 11:13:12