解決Vue引入百度地圖JSSDK:BMap is undefined 問題
阿新 • • 發佈:2018-11-14
原文連結: 解決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 +"&ak="+ AK +"&services=&t=" + timestamp;
return new Promise((resolve, reject) => {
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(() => {
// 超時10秒載入失敗
if(timeout >= 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&ak="+ AK +"&s=1&callback=onBMapCallback";
return new Promise((resolve, reject) => {
// 如果已載入直接返回
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,無法正常使用。