解決Vue引入百度地圖JSSDK:BMap is undefined 問題

百度地圖官網文檔介紹使用JSSDK時,僅提供了2種引入方式:javascript

  • script引入
  • 異步加載

解決跨域問題,實例調用百度地圖
html

但vue項目中僅某一兩個頁面須要用到百度地圖,因此不想在 index.html 中全局引用。vue


那在單個vue組件頁面中如何引入呢?java


剛開始時,是直接經過 DOM 操做方式插入script標籤到當前document中,以下:segmentfault

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);

結果是不行的。api

而後考慮使用異步加載的方式,結合參考網上方案,單首創建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("加載成功...")
    })
}
...

結果仍是不行。瀏覽器

想了下緣由,1、多是vue中window.onload沒有觸發,2、百度地圖JSSDK沒有真正加載成功。app

繼續驗證測試,發現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,沒法正常使用。

原文地址:http://www.javashuo.com/article/p-gkqnorig-bx.html

相關文章
相關標籤/搜索