百度地图官网文档介绍使用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

解决Vue引入百度地图JSSDK:BMap is undefined 问题的更多相关文章

  1. 解决vue中百度地图覆盖物引用本地图片问题

    这次的主要目的是在百度地图中引用自定义的覆盖物,路径是再asset/images/文件夹下,直接引用出错.需要先导入再引用. 在<script></script>代码中增加如下 ...

  2. 关于打包测试环境,百度地图报 Bmap not undefined

    https的网站使用百度地图,如果你引用的地址没写对的话,加载不出来百度地图,被认为是不安全的JS内容. https://api.map.baidu.com/api?+你的秘钥+&s=1 应该 ...

  3. vue引入百度地图 --BMap is not defined ,eslint BMap报错

    在mounted初始化地图的时候,因为异步问题会导致BMap is not defined,也就是百度的api还没完全引入或者加载完成,就已经进行地图初始化了 解决方法: 1.创建一个map.js e ...

  4. vue引入百度地图api组件封装(根据地址定位)

    Map.vue <template> <div class="Map" :style="{ height: this.height+'px', widt ...

  5. 单页面应用(spa)引入百度地图(Cannot read property 'dc' of undefined)

    难点介绍 引入百度地图的时候,用原生的获取不到dom节点. ( var mapEle = document.getElementById(testApi): var map = new BMap.Ma ...

  6. Angular/Vue调用百度地图+标注点不显示图标+多标注点计算地图中心位置

    整理一下~ 一.在vue中调用百度地图 首先当然是申请百度密匙(很简单,不多说) 1.在index.html文件中引入百度地图JavaScript API接口:   <script type=& ...

  7. Echarts3.0 引入百度地图(转载)

    转载来源: https://blog.csdn.net/yc_1993/article/details/52431989 Echarts3.0引入百度地图 update: 由于目前echarts3.8 ...

  8. react项目中引入百度地图打包报错问题

    一.我正常引入百度地图,调试时候是好使的,但是打包时候就报错 引入方法如下: 报错如图 正常调试是好使的,但是打包报这个错,解析不了这个BMap,那么怎么办呢? 然后我就转用了window办法,虽然因 ...

  9. react 自定义 百度地图(BMap)组件

    1.html 页面引入 相关js public/index.html <!DOCTYPE html> <html lang="en"> <head&g ...

随机推荐

  1. luogu P2000 拯救世界 生成函数_麦克劳林展开_python

    模板题. 将所有的多项式按等比数列求和公式将生成函数压缩,相乘后麦克劳林展开即可. Code: n=int(input()) print((n+1)*(n+2)*(n+3)*(n+4)//24)

  2. org.xml.sax.SAXParseException: Failed to read schema document 的原因分析与解决方法

    现象: org.xml.sax.SAXParseException: schema_reference.4: Failed to read schema documen t 'http://www.s ...

  3. BZOJ 4044 Virus synthesis (回文自动机+dp)

    题目大意: 你可以在一个串的开头或者末尾加入一个字符,或者把当前整个串$reverse$,然后接在前面或者后面,求达到目标串需要的最少操作次数 对目标串建出$PAM$ 定义$dp[x]$表示当前在回文 ...

  4. Jquery JS 全局变量

    window["a1"]="abc";window["b1"]=5;

  5. HDU3001 Traveling (状压dp+三进制+Tsp问题总结)

    (1)这道题最多可以走两次,所以有0, 1, 2三种状态,所以我们要用三进制 如果要用三进制,就要自己初始化两个数组, 一个是3的n次方,一个是三进制数的第几位的数字是什么 void init() { ...

  6. STM32 的 printf() 函数串口重定向(HAL库标准库都适用)

    1.建立工程 2.核心:添加新文件usar_fputc.c (名字随便自己命名),把文件添加到项目中去 #include "stdio.h" #include "stm3 ...

  7. Mysql如何避免全表扫描的方法

    在以下几种条件下,MySQL就会做全表扫描: 1>数据表是在太小了,做一次全表扫描比做索引键的查找来得快多了.当表的记录总数小于10且记录长度比较短时通常这么做. 2>没有合适用于 ON ...

  8. 洛谷——T P2136 拉近距离

    https://www.luogu.org/problem/show?pid=2136 题目背景 我是源点,你是终点.我们之间有负权环. ——小明 题目描述 在小明和小红的生活中,有N个关键的节点.有 ...

  9. ZOJ 2705

    这题,找找规律,可以发现一个斐波那契数列.按照斐波那契数列求和,知道, SUM=Fn+2-F1,于是,该长度为Fn+2的倍数.因为斐波那契数列不一定是从1开始的,而从2开始的每个数都是从1开始的倍数. ...

  10. 阿里云部署Docker(8)----安装和使用redmine

    安装redmine对过程进行管理. 须要说明的是:当你在docker images的时候,会说没连接到xxxx的时候,并且会提示用"docker -d".事实上这仅仅是把docke ...