腾讯位置服务学习记录
1.跨域
遇到的第一个“天灾”就是需要跨域:
utils/jsonp.ts
// eslint-disable-next-line func-names
export const jsonp = function (url: string, data: { [x: string]: any; key?: string; output?: string; sig?: string }) {
return new Promise((resolve, reject) => {
// 1.初始化url
const dataString = !url.includes('?') ? '?' : '&';
// eslint-disable-next-line no-param-reassign
url += `${dataString}callback=jsonpCallback`;
if (data) {
// 2.有请求参数,依次添加到url
// eslint-disable-next-line guard-for-in
for (const k in data) {
// eslint-disable-next-line no-param-reassign
url += `&${k}=${data[k]}`;
}
}
const scriptNode = document.createElement('script');
scriptNode.src = url;
// 3. callback
window.jsonpCallback = (result: any) => {
// eslint-disable-next-line @typescript-eslint/no-unused-expressions, prefer-promise-reject-errors
result ? resolve(result) : reject('没有返回数据');
delete window.jsonpCallback;
document.body.removeChild(scriptNode);
};
// 4. 异常情况
scriptNode.addEventListener(
'error',
() => {
// eslint-disable-next-line prefer-promise-reject-errors
reject('接口返回数据失败');
delete window.jsonpCallback;
document.body.removeChild(scriptNode);
},
false
);
// 5. 开始请求
document.body.appendChild(scriptNode);
});
};
这里有两点:
①:如果是ts出现的问题,但不影响流程,能用快速修复就用。
②:学到了一个新东西。关于TypeScript 扩展全局 Window 时报错「类型“Window & typeof globalThis”上不存在属性“xx”」的解决方案【TS+已解决】-CSDN博客
declare global {
export interface Window {
/** NProgress instance */
NProgress?: import('nprogress').NProgress;
/** Loading bar instance */
$loadingBar?: import('naive-ui').LoadingBarProviderInst;
/** Dialog instance */
$dialog?: import('naive-ui').DialogProviderInst;
/** Message instance */
$message?: import('naive-ui').MessageProviderInst;
/** Notification instance */
$notification?: import('naive-ui').NotificationProviderInst;
/** jsonp */
jsonpCallback: any;
}
export interface baseParams {
[key: string]: any;
}
/** Build time of the project */
export const BUILD_TIME: string;
}
2.sig签名验证
签名验证我真的找了挺多的文档去看,相关文档如下:
常见问题 | 腾讯位置服务
vue3 腾讯地图 WebServiceAPI 使用签名检验 jsonp获取数据_腾讯地图怎么使用签名-CSDN博客
最后我写的代码为:
onst getLocation = async () => {
const publicKey = 'KEY';
const secretKey = 'SK';
const param: { [key: string]: any } = {
key: publicKey,
output: 'jsonp',
callback: 'jsonpCallback'
};
const sortedParams = Object.keys(param)
.sort()
.map(k => `${k}=${encodeURIComponent(param[k])}`)
.join('&');
const sigStr = `/ws/location/v1/ip?${sortedParams}${secretKey}`;
let sig = md5(sigStr);
sig = encodeURI(sig);
// 添加签名到请求参数
const finalParams = {
key: publicKey,
output: 'jsonp',
sig
};
// 发送请求
const res: any = await jsonp('https://apis.map.qq.com/ws/location/v1/ip', { ...finalParams });
location.value = `${res.result.location.lat},${res.result.location.lng}`;
updateSearchParams({
location: location.value
});
getData();
};
这里是把jsonpCallback写死了。。。
import { md5 } from 'js-md5';
import { jsonp } from '@/utils/jsonp';
onMounted(() => getLocation());