解决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,无法正常使用。
原文地址:https://segmentfault.com/a/1190000012815739
解决Vue引入百度地图JSSDK:BMap is undefined 问题的更多相关文章
- 解决vue中百度地图覆盖物引用本地图片问题
这次的主要目的是在百度地图中引用自定义的覆盖物,路径是再asset/images/文件夹下,直接引用出错.需要先导入再引用. 在<script></script>代码中增加如下 ...
- 关于打包测试环境,百度地图报 Bmap not undefined
https的网站使用百度地图,如果你引用的地址没写对的话,加载不出来百度地图,被认为是不安全的JS内容. https://api.map.baidu.com/api?+你的秘钥+&s=1 应该 ...
- vue引入百度地图 --BMap is not defined ,eslint BMap报错
在mounted初始化地图的时候,因为异步问题会导致BMap is not defined,也就是百度的api还没完全引入或者加载完成,就已经进行地图初始化了 解决方法: 1.创建一个map.js e ...
- vue引入百度地图api组件封装(根据地址定位)
Map.vue <template> <div class="Map" :style="{ height: this.height+'px', widt ...
- 单页面应用(spa)引入百度地图(Cannot read property 'dc' of undefined)
难点介绍 引入百度地图的时候,用原生的获取不到dom节点. ( var mapEle = document.getElementById(testApi): var map = new BMap.Ma ...
- Angular/Vue调用百度地图+标注点不显示图标+多标注点计算地图中心位置
整理一下~ 一.在vue中调用百度地图 首先当然是申请百度密匙(很简单,不多说) 1.在index.html文件中引入百度地图JavaScript API接口: <script type=& ...
- Echarts3.0 引入百度地图(转载)
转载来源: https://blog.csdn.net/yc_1993/article/details/52431989 Echarts3.0引入百度地图 update: 由于目前echarts3.8 ...
- react项目中引入百度地图打包报错问题
一.我正常引入百度地图,调试时候是好使的,但是打包时候就报错 引入方法如下: 报错如图 正常调试是好使的,但是打包报这个错,解析不了这个BMap,那么怎么办呢? 然后我就转用了window办法,虽然因 ...
- react 自定义 百度地图(BMap)组件
1.html 页面引入 相关js public/index.html <!DOCTYPE html> <html lang="en"> <head&g ...
随机推荐
- EntityFramework 一
EntityFramework EF核心库 EntityFramework.SqlServer EF针对sqlsever的库 引用 system.Data.Entity EF相比SQL语句方便,但 ...
- HDU 5288 OO’s Sequence [数学]
HDU 5288 OO’s Sequence http://acm.hdu.edu.cn/showproblem.php?pid=5288 OO has got a array A of size ...
- POJ 3517 And Then There Was One( 约瑟夫环模板 )
链接:传送门 题意:典型约瑟夫环问题 约瑟夫环模板题:n个人( 编号 1-n )在一个圆上,先去掉第m个人,然后从m+1开始报1,报到k的人退出,剩下的人继续从1开始报数,求最后剩的人编号 /**** ...
- Flask入门系列(转载)
一.入门系列: Flask入门系列(一)–Hello World 项目开发中,经常要写一些小系统来辅助,比如监控系统,配置系统等等.用传统的Java写,太笨重了,连PHP都嫌麻烦.一直在寻找一个轻量级 ...
- Python 绘图与可视化 seaborn
Seaborn是一个基于matplotlib的Python数据可视化库.它提供了一个高级界面,用于绘制有吸引力且信息丰富的统计图形. 主页:http://seaborn.pydata.org/ 官方教 ...
- 洛谷P1138 第k小整数
我偏不用sort Treap好题啊 看到只有一个人写Treap,而且写的不清楚,那我就来详细地写一下,方便新人学习 第(-1)部分:前置知识 二叉查找树:满足左子树的数据都比根节点小,右子树的数据都比 ...
- 使用Modernizr检测支持CSS3
使用Modernizr检测支持CSS3 如果支持某个属性,会增加一个class,名字就是该属性: 不支持,名字是no-某属性 还提供了一个全局Modernizr对象,使用如下: <script ...
- debian mysql 定时自己主动备份的脚本
#!/bin/sh LOG=/var/log/mysql-backup.log # mysql db info USER_ROOT=XXXXXX USER_PWD=XXXXXXX # mysql da ...
- JDBC创建mysql连接池代码
1.底层实现类(DBConnection) package JDBC.JDBCPool.MyJDBCPool; import java.sql.Connection; import java.sql. ...
- FPGA之阻塞赋值与非阻塞赋值
Verilog语言中讲的阻塞赋值与非阻塞赋值,但从字面意思来看,阻塞就是执行的时候在某个地方卡住了,等这个操作执行完在继续执行下面的语句,而非阻塞就是不管执行完没有,我不管执行的结果是什么,反正我继续 ...