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


百度地圖官網文檔介紹使用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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM