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
相关产品推荐
相关产品推荐

