Vue引入百度地图JSSDK:BMap 异步问题

百度地图BMap undefind?异步加载解决方案

百度地图官网文档介绍使用JSSDK时,仅提供了2种引入方式:

  • script引入
  • 异步加载

解决跨域问题,实例调用百度地图

但vue项目中仅某一两个页面需要用到百度地图,所以不想在 index.html 中全局引用。

那在单个vue组件页面中如何引入呢?

刚开始时,是直接通过 DOM 操作方式插入script标签到当前document中,如下:

let scriptNode = document.createElement("script");
scriptNode.setAttribute("type", "text/javascript");
scriptNode.setAttribute("src", "http://api.map.baidu.com/api?v=3.0&ak=您的**");
document.body.appendChild(scriptNode);

结果是不行的。

然后考虑使用异步加载的方式,结合参考网上方案,单独创建baidu-map.js脚本:

 
export default {
  init: function (){
    const AK = "AK**";
    const apiVersion = "3.0";
    const timestamp = new Date().getTime();
    const BMap_URL = "http://api.map.baidu.com/api?v="+ apiVersion +"&ak="+ AK +"&services=&t=" + timestamp;
    return new Promise((resolve, reject) => {
      // 插入script脚本
      let scriptNode = document.createElement("script");
      scriptNode.setAttribute("type", "text/javascript");
      scriptNode.setAttribute("src", BMap_URL);
      document.body.appendChild(scriptNode);
 
      // 等待页面加载完毕回调
      window.onload = function () {  
         resolve(BMap)  
       } 
    });
  }
}
 
// -------------------------
// vue引入调用
import BaiduMap from 'baidu-map';
 
...
mounted(){
    BauduMap.init()
    .then((BMap) => {
        console.log(BMap)
        console.log("加载成功...")
    })
}
...  

结果还是不行。

想了下原因,一、可能是vue中window.onload没有触发,二、百度地图JSSDK没有真正加载成功。

继续验证测试,发现window.onload能够正常触发,那就是JSSDK没有加载成功。

直接复制JSSDK URL浏览器中打开 http://api.map.baidu.com/api?v=3.0&ak=您的**关键点来了,打开后内容如下:

(function(){ 
window.BMap_loadScriptTime = (new Date).getTime(); 
document.write('<script type="text/javascript" src="http://api.map.baidu.com/getscript?v=3.0&ak=您的**&services=&t=20180102163224"></script>');
})();

从返回内容中看出,立即执行函数中再次插入了另外一个<scirpt>标签,经检查发现这个<scirpt>实际并没有插入成功。

既然如此,那就直接把脚本放到我们上面的代码中去加载,结果就真的成功了。

修改优化后的代码如下:

 
export default {
  init: function (){
    console.log("初始化百度地图脚本...");
    const AK = "AK**";
    const apiVersion = "3.0";
    const timestamp = new Date().getTime();
    const BMap_URL = "http://api.map.baidu.com/getscript?v="+ apiVersion +"&amp;ak="+ AK +"&amp;services=&amp;t=" + timestamp;
    return new Promise((resolve, reject) =&gt; {
      if(typeof BMap !== "undefined") {
        resolve(BMap);
        return true;
      }
 
      // 插入script脚本
      let scriptNode = document.createElement("script");
      scriptNode.setAttribute("type", "text/javascript");
      scriptNode.setAttribute("src", BMap_URL);
      document.body.appendChild(scriptNode);
 
      // 等待页面加载完毕回调
      let timeout = 0;
      let interval = setInterval(() =&gt; {
        // 超时10秒加载失败
        if(timeout &gt;= 20) {
          reject();
          clearInterval(interval);
          console.error("百度地图脚本初始化失败...");
        }
        // 加载成功
        if(typeof BMap !== "undefined") {
          resolve(BMap);
          clearInterval(interval);
          console.log("百度地图脚本初始化成功...");
        }
        timeout += 1;
      }, 500);
    });
  }
}  

问题到此就解决了,至于为什么用官网提供的地址没有真正加载到JSSDK这个问题有空再研究下。

最新解决方案

export default {
  init: function (){
    //console.log("初始化百度地图脚本...");
    const AK = "AK**";
    const BMap_URL = "https://api.map.baidu.com/api?v=2.0&amp;ak="+ AK +"&amp;s=1&amp;callback=onBMapCallback";
    return new Promise((resolve, reject) =&gt; {
      // 如果已加载直接返回
      if(typeof BMap !== "undefined") {
        resolve(BMap);
        return true;
      }
      // 百度地图异步加载回调处理
      window.onBMapCallback = function () {
        console.log("百度地图脚本初始化成功...");
        resolve(BMap);
      };
 
      // 插入script脚本
      let scriptNode = document.createElement("script");
      scriptNode.setAttribute("type", "text/javascript");
      scriptNode.setAttribute("src", BMap_URL);
      document.body.appendChild(scriptNode);
    });
  }
}  

优化如下:

  • 直接使用官网提供的引用地址:http://api.map.baidu.com/api?v=2.0&ak=您的**
  • 启用 callback 参数,异步加载必须使用此参数才可以生效
  • 启用 https 配置,通过 s=1 参数实现
  • API版本为2.0,经测试使用,发现3.0版本在HTTPS环境下是有问题的,脚本内部某些请求固定使用HTTP,无法正常使用。

原文地址:https://segmentfault.com/a/1190000012815739

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容