遇到这么个需求,跨域请求数据,需要请求某个数据直到获取到数据为止(没有使用socket,因为后端是来自本地的exe不一定一直在启动中),为了追求浏览器兼容性,没有选择cors
用的传统的jsonp,结合Promise(低版本浏览器可以手动实现)
代码如下
//import uuid from "@/utils/uuid"; //可以无视,js生成一个唯一标志
export default function JSONP(url, id,debounce) {
this.id = id //|| uuid(true); 可以无视,js生成一个唯一标志
this.debounce = debounce||500; //节流
this.getData = function () {
let _this = this;
return new Promise(function (resolve, reject) {
let script = document.createElement("script");
script.src = url + (url.indexOf("?") > -1 ? "&" : "?") + "f=" + _this.id+"&t="+new Date().getTime(); //解决ie轮询get请求优先使用缓存的bug
//后端接收参数f,然后返回window.f=值; 具体不详细展开了
script.async = true;
script.id = _this.id;
document.head.appendChild(script);
script.onload = function () {
resolve(window[_this.id]);
/*2021/12/03 更新*/
setTimeout(function(){
document.head.removeChild(script);
},500)
}
script.onerror = function () {
/*2021/12/03 更新*/
document.head.removeChild(script);
console.log("load script error");
setTimeout(function(){
reject();
},_this.debounce);
}
});
}
}
export function JSONPS(option, callback) {
if (option && option.url && option.id) {
if (!option._time) {
option._time = 1;
option._initDate = new Date().getTime();
}
else {
option._time = option._time + 1;
}
let jsonp = new JSONP(option.uri, option.id);
jsonp.getData().then(res => {
if (callback) {
callback(res);
}
}, err => {
if (option.timeout && typeof(option.timeout)=='number') {
if ((option.timeout + option._initDate) > new Date().getTime()) {
JSONPS(option.uri, option.id);
}
else{
console.log("jsonp time out");
}
}
else {
if(typeof(option.stop)=='undefined'){
JSONPS(option.uri, option.id);
}
}
})
}
}
使用如下
//import {JSONPS} from xxx;
let option={
url:"http://xxxx:xxxx",
id:"aaaa",
timeout:30000 //不写的话就一直运行下去,直到给option添加一个option.stop=1
}
JSONPS(option,r=>{
//获取到后端数据r执行其他代码
})