(function (global, factory) { "use strict"; if (typeof module === "object" && typeof module.exports === "object") { module.exports = factory(global, true); } else { if (typeof define === 'function' && define.amd) { define(factory); } else { factory(global); } } })(typeof window !== "undefined" ? window : this, function (window, noGlobal) { "use strict"; /** * http状态码,对应的返回信息,由于websocket不存在状态码,暂时由前端对返回信息进行匹配 错误码:406 错误信息:Failed to send message to WPS 错误码:406 错误信息:Json parse failed 错误码:406 错误信息:Product not found 错误码:406 错误信息:Failed 错误码:403 错误信息:Forbidden 错误码:503 错误信息:Service Unavailable 错误码:417 错误信息:WPSInnerMessage_InvalidBusinessId */ var httpCodeErrorMessageList = [ 'Failed to send message to WPS', 'Json parse failed', 'Product not found', 'Failed', 'Forbidden', 'Service Unavailable', 'WPSInnerMessage_InvalidBusinessId' ] var bFinished = true; var serverVersion = 'wait'; var wpsinvokeNetType='wait'; if(sessionStorage.getItem('wpsinvokeNetType')) { wpsinvokeNetType = sessionStorage.getItem('wpsinvokeNetType'); }; if(sessionStorage.getItem('serverVersion')) { serverVersion = sessionStorage.getItem('serverVersion'); }; function isReplaceWebSocket() { if( wpsinvokeNetType === 'websocket' ) { return true; } else { return false; }; } /** * ws、http互相替换链接 * @param {*} url 请求链接 * @returns */ function transferWebsocketToHttp(url) { return url.replace('ws://','http://').replace(':58892',':58890'); } function transferHttpToWebsocket(url) { return url.replace('http://','ws://').replace(':58890',':58892'); } /** * 获取网页路径前缀 * @returns url前缀 */ function GetUrlBase() { if(isReplaceWebSocket()){ if (location.protocol == "https:") return 'wss://127.0.0.1:58893' return 'ws://127.0.0.1:58892' } return getHttpUrl(); } /** * 获取http链接 */ function getHttpUrl (){ if (location.protocol == "https:") return "https://127.0.0.1:58891" return "http://127.0.0.1:58890" } /** * 兼容IE低版本Array没有indexOf方法的场景 */ if (!Array.prototype.indexOf) { Array.prototype.indexOf = function (elt /*, from*/) { var len = this.length >>> 0; var from = Number(arguments[1]) || 0; from = (from < 0) ? Math.ceil(from) : Math.floor(from); if (from < 0) from += len; for (; from < len; from++) { if (from in this && this[from] === elt) return from; } return -1; }; } /** * 判断是否函数 */ function isFunction(func) { return typeof func === 'function'; } /** * websocket对象 */ function getWebsocketObj(){ this.onopen = null; this.onmessage = null; this.onclose = null; this.onerror = null; this.wsInstance = null; } getWebsocketObj.prototype.connect = function(url) { var that = this; var ws = that.wsInstance = new WebSocket(url); ws.onopen = function(res) { if(isFunction(that.onopen)) { that.onopen(res); } } ws.onmessage = function(res) { if(isFunction(that.onmessage)) { that.onmessage(res); } } ws.onclose = function(res) { if(isFunction(that.onclose)) { that.onclose(res); } } ws.onerror = function(res) { if(isFunction(that.onerror)) { that.onerror(res); } } } getWebsocketObj.prototype.send = function(data) { if(this.wsInstance) { this.wsInstance.send(data) } } getWebsocketObj.prototype.close = function() { if(this.wsInstance) { this.wsInstance.close() } } /** * 兼容IE低版本的创建httpobj对象的方法 * @returns httpobj,可用于进行数据传输的http的对象 */ function getHttpObj() { var httpobj = null; if (IEVersion() < 10) { try { httpobj = new XDomainRequest(); } catch (e1) { httpobj = new createXHR(); } } else { httpobj = new createXHR(); } return httpobj; } //兼容IE低版本的创建xmlhttprequest对象的方法 /** * 兼容IE低版本的创建xmlhttprequest对象的方法 * @returns xmlhttprequest对象,兼容低版本IE */ function createXHR() { if (typeof XMLHttpRequest != 'undefined') { //兼容高版本浏览器 return new XMLHttpRequest(); } else if (typeof ActiveXObject != 'undefined') { //IE6 采用 ActiveXObject, 兼容IE6 var versions = [ //由于MSXML库有3个版本,因此都要考虑 'MSXML2.XMLHttp.6.0', 'MSXML2.XMLHttp.3.0', 'MSXML2.XMLHttp' ]; for (var i = 0; i < versions.length; i++) { try { return new ActiveXObject(versions[i]); } catch (e) { //跳过 } } } else { throw new Error('您的浏览器不支持XHR对象'); } } /** * 加载项本地服务返回的错误信息,统一为data : message的json格式 * 如果有新增错误信息,添加到下面 * 也可以通过请求状态码返回错误信息 */ var errorMsg = [ "{\"data\": \"Failed to send message to WPS.\"}", "{\"data\": \"Json parse failed.\"}", "{\"error\": \"Json parse failed.\"}" ] /** * 通过该接口给服务器发请求 * @param {*} options 参数对象,具体包含的参数如下: * @param {*} url 网页路径,传输地址 * @param {*} type 传输类型,POST / GET / PUT * @param {*} sendData 传输的数据 * @param {*} callBack 回调函数 * @param {*} tryCount 请求失败后的尝试次数 * @param {*} bPop 是否弹出浏览器提示对话框 * @param {*} timeout 请求等待响应的时间,超过时间请求实效 * @param {*} concurrent 请求是否同步发送 * @param {*} wpsclient wpsclient对象 * @returns NULL */ function startWps(options) { if (!bFinished && !options.concurrent) { if (options.callBack) options.callBack({ status: 1, message: "上一次请求没有完成" }); return; } if (!options.concurrent) bFinished = false; else options.bFinished = false; function startWpsInnder(tryCount) { if (tryCount <= 0) { // http失败重试时,会唤醒云服务,当重试次数清0时,向云服务发起一次ws请求确认是否是浏览器安全问题 if(serverVersion === 'wait' && wpsinvokeNetType === 'wait') { options.url = transferHttpToWebsocket(options.url); startWpsInnderWebsocket(1); return }; if (!options.concurrent) { if (bFinished) return; bFinished = true; } else { if (options.bFinished) { return; } options.bFinished = true; } if (options.callBack) options.callBack({ status: 2, message: "请允许浏览器打开WPS Office" }); return; } var xmlReq = getHttpObj(); //WPS客户端提供的接收参数的本地服务,HTTP服务端口为58890,HTTPS服务端口为58891 //这俩配置,取一即可,不可同时启用 xmlReq.open('POST', options.url); xmlReq.onload = function (res) { wpsinvokeNetType="http" sessionStorage.setItem("wpsinvokeNetType",wpsinvokeNetType); var responseStr = IEVersion() < 10 ? xmlReq.responseText : res.target.response; var respStatus = IEVersion() < 10 ? xmlReq.status : res.target.status; if (!options.concurrent) bFinished = true; else options.bFinished = true; if (options.callBack) { if ((respStatus != undefined && respStatus != 200) || errorMsg.indexOf(responseStr) != -1) { var errorMessage = JSON.parse(responseStr) options.callBack({ status: 1, message: errorMessage.data }); if (errorMessage.data == "Subserver not available." && tryCount == options.tryCount && options.bPop) { InitWpsCloudSvr(); setTimeout(function () { startWpsInnder(tryCount - 1) }, 3000); } } else { options.callBack({ status: 0, response: responseStr }); } } } xmlReq.ontimeout = xmlReq.onerror = function (res) { xmlReq.bTimeout = true; if (tryCount == options.tryCount && options.bPop&&wpsinvokeNetType=="wait") { //打开wps并传参 InitWpsCloudSvr(); } setTimeout(function () { startWpsInnder(tryCount - 1) }, 1000); } if (IEVersion() < 10) { xmlReq.onreadystatechange = function () { if (xmlReq.readyState != 4) return; if (xmlReq.bTimeout) { return; } if (xmlReq.status === 200) xmlReq.onload(); else xmlReq.onerror(); } } xmlReq.timeout = options.timeout; xmlReq.send(options.sendData) } function startWpsInnderWebsocket(tryCount){ // 重试次数结束时,标记请求已完成 if (tryCount <= 0) { if (!options.concurrent) { if (bFinished) return; bFinished = true; } else { if (options.bFinished) { return; } options.bFinished = true; } if (options.callBack) options.callBack({ status: 2, message: "请允许浏览器打开WPS Office" }); return; } var ws = new getWebsocketObj({ timeout:options.timeout }); ws.connect(options.url); ws.onmessage = function(res) { wpsinvokeNetType="websocket" sessionStorage.setItem("wpsinvokeNetType",wpsinvokeNetType); var responseStr = res.data; if (!options.concurrent) bFinished = true; else options.bFinished = true; if (options.callBack) { if (errorMsg.indexOf(responseStr) != -1 || httpCodeErrorMessageList.indexOf(responseStr) != -1 ) { var errorMessage = JSON.parse(responseStr); options.callBack({ status: 1, message: errorMessage.data }); if (errorMessage.data == "Subserver not available." && tryCount == options.tryCount && options.bPop) { InitWpsCloudSvr(); setTimeout(function () { startWpsInnderWebsocket(tryCount - 1) }, 3000); } } else { options.callBack({ status: 0, response: res.data }); } } ws.close(); } ws.onerror = function(res){ if (tryCount == options.tryCount && options.bPop&&wpsinvokeNetType=="wait") { //打开wps并传参 InitWpsCloudSvr(); } setTimeout(function () { startWpsInnderWebsocket(tryCount - 1) }, 1000); } ws.onopen = function(res){ ws.send(options.sendData); } } if(isReplaceWebSocket()){ startWpsInnderWebsocket(options.tryCount); } else { startWpsInnder(options.tryCount); } return; } var fromCharCode = String.fromCharCode; // encoder stuff var cb_utob = function (c) { if (c.length < 2) { var cc = c.charCodeAt(0); return cc < 0x80 ? c : cc < 0x800 ? (fromCharCode(0xc0 | (cc >>> 6)) + fromCharCode(0x80 | (cc & 0x3f))) : (fromCharCode(0xe0 | ((cc >>> 12) & 0x0f)) + fromCharCode(0x80 | ((cc >>> 6) & 0x3f)) + fromCharCode(0x80 | (cc & 0x3f))); } else { var cc = 0x10000 + (c.charCodeAt(0) - 0xD800) * 0x400 + (c.charCodeAt(1) - 0xDC00); return (fromCharCode(0xf0 | ((cc >>> 18) & 0x07)) + fromCharCode(0x80 | ((cc >>> 12) & 0x3f)) + fromCharCode(0x80 | ((cc >>> 6) & 0x3f)) + fromCharCode(0x80 | (cc & 0x3f))); } }; var re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g; var utob = function (u) { return u.replace(re_utob, cb_utob); }; var _encode = function (u) { var isUint8Array = Object.prototype.toString.call(u) === '[object Uint8Array]'; if (isUint8Array) return u.toString('base64') else return btoa(utob(String(u))); } if (typeof window.btoa !== 'function') window.btoa = func_btoa; function func_btoa(input) { var str = String(input); var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; for ( // initialize result and counter var block, charCode, idx = 0, map = chars, output = ''; // if the next str index does not exist: // change the mapping table to "=" // check if d has no fractional digits str.charAt(idx | 0) || (map = '=', idx % 1); // "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8 output += map.charAt(63 & block >> 8 - idx % 1 * 8) ) { charCode = str.charCodeAt(idx += 3 / 4); if (charCode > 0xFF) { throw new InvalidCharacterError("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range."); } block = block << 8 | charCode; } return output; } if (typeof window.atob !== 'function') window.atob = func_atob; function func_atob(input) { var output = input.replace(/[\s\S]{1,4}/g, cb_decode); return output } function cb_decode(cccc) { var len = cccc.length , padlen = len % 4 , n = (len > 0 ? b64tab[cccc.charAt(0)] << 18 : 0) | (len > 1 ? b64tab[cccc.charAt(1)] << 12 : 0) | (len > 2 ? b64tab[cccc.charAt(2)] << 6 : 0) | (len > 3 ? b64tab[cccc.charAt(3)] : 0) , chars = [ fromCharCode(n >>> 16), fromCharCode((n >>> 8) & 0xff), fromCharCode(n & 0xff) ] ; chars.length -= [0, 0, 2, 1][padlen]; return chars.join(''); }; function btou(b) { return b.replace(re_btou, cb_btou); }; // decoder stuff var re_btou = new RegExp([ '[\xC0-\xDF][\x80-\xBF]', '[\xE0-\xEF][\x80-\xBF]{2}', '[\xF0-\xF7][\x80-\xBF]{3}' ].join('|'), 'g'); function cb_btou(cccc) { switch (cccc.length) { case 4: var cp = ((0x07 & cccc.charCodeAt(0)) << 18) | ((0x3f & cccc.charCodeAt(1)) << 12) | ((0x3f & cccc.charCodeAt(2)) << 6) | (0x3f & cccc.charCodeAt(3)), offset = cp - 0x10000; return (fromCharCode((offset >>> 10) + 0xD800) + fromCharCode((offset & 0x3FF) + 0xDC00)); case 3: return fromCharCode( ((0x0f & cccc.charCodeAt(0)) << 12) | ((0x3f & cccc.charCodeAt(1)) << 6) | (0x3f & cccc.charCodeAt(2)) ); default: return fromCharCode( ((0x1f & cccc.charCodeAt(0)) << 6) | (0x3f & cccc.charCodeAt(1)) ); } }; /** * 将字符串进行Base64编码 * @param {*} u 需要编码的数据 * @param {*} urisafe 返回值,编码后的数据 * @returns urisafe */ var encode = function (u, urisafe) { return !urisafe ? _encode(u) : _encode(String(u)).replace(/[+\/]/g, function (m0) { return m0 == '+' ? '-' : '_'; }).replace(/=/g, ''); }; var decode = function (u) { return btou(atob(String(u))); } /** * 获取IE浏览器版本 * @returns IE浏览器版本 */ function IEVersion() { var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串 var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判断是否IE<11浏览器 var isEdge = userAgent.indexOf("Edge") > -1 && !isIE; //判断是否IE的Edge浏览器 var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf("rv:11.0") > -1; if (isIE) { var reIE = new RegExp("MSIE (\\d+\\.\\d+);"); reIE.test(userAgent); var fIEVersion = parseFloat(RegExp["$1"]); if (fIEVersion == 7) { return 7; } else if (fIEVersion == 8) { return 8; } else if (fIEVersion == 9) { return 9; } else if (fIEVersion == 10) { return 10; } else { return 6; //IE版本<=7 } } else if (isEdge) { return 20; //edge } else if (isIE11) { return 11; //IE11 } else { return 30; //不是ie浏览器 } } /** * 启动wps客户端,加载项执行操作,无返回值 * @param {*} options 参数对象,详情见下: * @param {*} clientType 加载项类型, wps / wpp / et * @param {*} name 加载项名称 * @param {*} func 客户端加载项要执行的方法 * @param {*} param 客户端家乡执行方法的参数 * @param {*} urlBase 网页路径前缀 * @param {*} callBack 回调函数 * @param {*} tryCount 请求失败后的尝试次数 * @param {*} bPop 是否弹出浏览器提示对话框 * @param {*} wpsclient wpsclient对象 */ function WpsStart(options) { var startInfo = { "name": options.name, "function": options.func, "info": options.param.param, "jsPluginsXml": options.param.jsPluginsXml }; var strData = JSON.stringify(startInfo); if (IEVersion() < 10) { try { eval("strData = '" + JSON.stringify(startInfo) + "';"); } catch (err) { } } var baseData = encode(strData); var url = options.urlBase + "/" + options.clientType + "/runParams"; var data = "ksowebstartup" + options.clientType + "://" + baseData; startWps({ url: url, sendData: data, callBack: options.callBack, tryCount: options.tryCount, bPop: options.bPop, timeout: 5000, concurrent: false, wpsclient: options.wpsclient }); } /** * 服务端版本为空时,通过该接口启动wps * @param {*} options 参数对象,详情见下: * @param {*} clientType 加载项类型, wps / wpp / et * @param {*} name 加载项名称 * @param {*} func 客户端加载项要执行的方法 * @param {*} param 客户端家乡执行方法的参数 * @param {*} urlBase 网页路径前缀 * @param {*} callBack 回调函数 * @param {*} wpsclient wpsclient对象 * @param {*} concurrent 请求是否同步发送 */ function WpsStartWrap(options) { WpsStart({ clientType: options.clientType, name: options.name, func: options.func, param: options.param, urlBase: options.urlBase, callBack: options.callBack, tryCount: 4, bPop: true, wpsclient: options.wpsclient, }) } /** * 支持浏览器触发,WPS有返回值的启动 * * @param {*} clientType 组件类型 * @param {*} name WPS加载项名称 * @param {*} func WPS加载项入口方法 * @param {*} param 参数:包括WPS加载项内部定义的方法,参数等 * @param {*} callBack 回调函数 * @param {*} tryCount 重试次数 * @param {*} bPop 是否弹出浏览器提示对话框 */ function WpsStartWrapExInner(options) { var infocontent = options.param.param; var cmdId = guid(); if (!options.wpsclient || options.wpsclient.single) { infocontent = JSON.stringify(options.param.param); var rspUrl = getHttpUrl() + "/transferEcho/runParams"; var funcEx = "var res = " + options.func; var cbCode = "var xhr = new XMLHttpRequest();xhr.open('POST', '" + rspUrl + "');xhr.send(JSON.stringify({id: '" + cmdId + "', response: res}));" //res 为func执行返回值 var infoEx = infocontent + ");" + cbCode + "void(0"; options.func = funcEx; infocontent = infoEx; } var startInfo = { "name": options.name, "function": options.func, "info": infocontent, "showToFront": options.param.showToFront, "jsPluginsXml": options.param.jsPluginsXml, }; var strData = JSON.stringify(startInfo); if (IEVersion() < 10) { try { eval("strData = '" + JSON.stringify(startInfo) + "';"); } catch (err) { } } var baseData = encode(strData); var wrapper; if (!options.wpsclient || options.wpsclient.single) { var url = options.urlBase + "/transfer/runParams"; var data = "ksowebstartup" + options.clientType + "://" + baseData; wrapper = { id: cmdId, app: options.clientType, data: data, serverId: serverId, mode: options.silentMode ? true : false, timeout: options.timeout, startparam: options.startparam, }; } else { var url = options.urlBase + "/transferEx/runParams"; wrapper = { id: options.wpsclient.clientId, app: options.clientType, data: baseData, mode: options.wpsclient.silentMode ? "true" : "false", serverId: serverId, timeout: options.timeout, startparam: options.startparam, }; } wrapper = JSON.stringify(wrapper); startWps({ url: url, sendData: wrapper, callBack: options.callBack, tryCount: options.tryCount, bPop: options.bPop, timeout: 0, concurrent: options.concurrent, wpsclient: options.wpsclient }); } /** * 获取服务端版本号的接口 * @param {*} options 参数对象,详情见下: * @param {*} clientType 加载项类型, wps / wpp / et * @param {*} name 加载项名称 * @param {*} func 客户端加载项要执行的方法 * @param {*} param 客户端家乡执行方法的参数 * @param {*} urlBase 网页路径前缀 * @param {*} callBack 回调函数 * @param {*} wpsclient wpsclient对象 * @param {*} concurrent 请求是否同步发送 */ function WpsStartWrapVersionInner(options) { if (serverVersion == "wait") { if (g_isSdkInited == true) { InitWpsCloudSvr(); } startWps({ url: options.urlBase + '/version', sendData: JSON.stringify({ serverId: serverId }), callBack: function (res) { if (res.status !== 0) { options.callBack(res) return; } serverVersion = res.response; sessionStorage.setItem('serverVersion', serverVersion); // 确定版本不能使用ws后,需要把未启动时定义好的协议调整回来 if(wpsinvokeNetType === 'websocket') { options.urlBase = transferWebsocketToHttp(options.urlBase) } if (options.isPublish != true) { options.tryCount = 1 options.bPop = false if (serverVersion === "") { WpsStart(options) } else if (serverVersion < "1.0.1" && options.wpsclient) { options.wpsclient.single = true; WpsStartWrapExInner(options); } else { WpsStartWrapExInner(options); } } else { if (serverVersion === "") { callBack({ status: 4, message: "当前客户端不支持,请升级客户端" }) } else { WpsAddonGetAllConfigInner(options.callBack) } } }, tryCount: 4, bPop: !g_isSdkInited, timeout: 5000, concurrent: options.concurrent }); } else { if (options.isPublish != true) { options.tryCount = 4 options.bPop = true if (serverVersion === "") { WpsStartWrap(options) } else if (serverVersion < "1.0.1" && options.wpsclient) { options.wpsclient.single = true; WpsStartWrapExInner(options); } else { WpsStartWrapExInner(options); } } else { if (serverVersion === "") { callBack({ status: 4, message: "当前客户端不支持,请升级客户端" }) } else { WpsAddonGetAllConfigInner(options.callBack) } } } } var HeartBeatCode = "function getHttpObj() {\n" + " var httpobj = null;\n" + " if (IEVersion() < 10) {\n" + " try {\n" + " httpobj = new XDomainRequest();\n" + " } catch (e1) {\n" + " httpobj = new createXHR();\n" + " }\n" + " } else {\n" + " httpobj = new createXHR();\n" + " }\n" + " return httpobj;\n" + " }\n" + " \n" + " function createXHR() {\n" + " if (typeof XMLHttpRequest != 'undefined') {\n" + " return new XMLHttpRequest();\n" + " } else if (typeof ActiveXObject != 'undefined') {\n" + " var versions = [\n" + " 'MSXML2.XMLHttp.6.0',\n" + " 'MSXML2.XMLHttp.3.0',\n" + " 'MSXML2.XMLHttp'\n" + " ];\n" + " \n" + " for (var i = 0; i < versions.length; i++) {\n" + " try {\n" + " return new ActiveXObject(versions[i]);\n" + " } catch (e) {\n" + " \n" + " }\n" + " }\n" + " } else {\n" + " throw new Error('您的浏览器不支持XHR对象');\n" + " }\n" + " }\n" + " \n" + " function IEVersion() {\n" + " var userAgent = navigator.userAgent; \n" + " var isIE = userAgent.indexOf('compatible') > -1 && userAgent.indexOf('MSIE') > -1;\n" + " var isEdge = userAgent.indexOf('Edge') > -1 && !isIE; \n" + " var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf('rv:11.0') > -1;\n" + " if (isIE) {\n" + " var reIE = new RegExp('MSIE (\\d+\\.\\d+);');\n" + " reIE.test(userAgent);\n" + " var fIEVersion = parseFloat(RegExp['$1']);\n" + " if (fIEVersion == 7) {\n" + " return 7;\n" + " } else if (fIEVersion == 8) {\n" + " return 8;\n" + " } else if (fIEVersion == 9) {\n" + " return 9;\n" + " } else if (fIEVersion == 10) {\n" + " return 10;\n" + " } else {\n" + " return 6; \n" + " }\n" + " } else if (isEdge) {\n" + " return 20; \n" + " } else if (isIE11) {\n" + " return 11; \n" + " } else {\n" + " return 30; \n" + " }\n" + " }\n" + " var heartBeatStart = false;\n" + " function checkLastRegTime() {\n" + " var now = new Date().valueOf();\n" + " var TimeGap = now - LastRegTime;\n" + " if (TimeGap > 5000 && !heartBeatStart) {\n" + " HeartBeat();\n" + " heartBeatStart = true;\n" + " }\n" + " }\n" + " \n" + " function HeartBeat() {\n" + " var heartBeatItem = function () {\n" + " var xhr = getHttpObj();\n" + " xhr.onload = function (e) {\n" + " self.setTimeout(heartBeatItem, 5000);\n" + " }\n" + " xhr.onerror = function (e) {\n" + " self.setTimeout(heartBeatItem, 5000);\n" + " }\n" + " xhr.ontimeout = function (e) {\n" + " self.setTimeout(heartBeatItem, 5000);\n" + " }\n" + " xhr.open('POST', 'http://127.0.0.1:58890/askwebnotify', true);\n" + " xhr.timeout = 2000;\n" + " xhr.send(JSON.stringify(paramStr));\n" + " }\n" + " heartBeatItem();\n" + " }\n" + " \n" + " var paramStr;\n" + " var startCheck = false;\n" + " self.addEventListener('message', function (event) {\n" + " var data = event.data;\n" + " paramStr = data.param\n" + " paramStr.heartBeat = true\n" + " LastRegTime = data.LastRegTime;\n" + " if (!startCheck) {\n" + " startCheck = true;\n" + " self.setInterval(checkLastRegTime, 5000)\n" + " }\n" + " }, false);\n" var HeartBeatCodeWebSocket = " // 判断是否函数 \n" + " function isFunction(func) { \n" + " return typeof func === 'function'; \n" + " } \n" + " // websocket对象 \n" + " function getWebsocketObj() { \n" + " this.onopen = null; \n" + " this.onmessage = null; \n" + " this.onclose = null; \n" + " this.onerror = null; \n" + " this.wsInstance = null; \n" + " } \n" + " getWebsocketObj.prototype.connect = function (url) { \n" + " var that = this; \n" + " var ws = (that.wsInstance = new WebSocket(url)); \n" + " ws.onopen = function (res) { \n" + " if (isFunction(that.onopen)) { \n" + " that.onopen(res); \n" + " } \n" + " }; \n" + " ws.onmessage = function (res) { \n" + " if (isFunction(that.onmessage)) { \n" + " that.onmessage(res); \n" + " } \n" + " }; \n" + " ws.onclose = function (res) { \n" + " if (isFunction(that.onclose)) { \n" + " that.onclose(res); \n" + " } \n" + " }; \n" + " ws.onerror = function (res) { \n" + " if (isFunction(that.onerror)) { \n" + " that.onerror(res); \n" + " } \n" + " }; \n" + " }; \n" + " getWebsocketObj.prototype.send = function (data) { \n" + " if (this.wsInstance) { \n" + " this.wsInstance.send(data); \n" + " } \n" + " }; \n" + " getWebsocketObj.prototype.close = function () { \n" + " if (this.wsInstance) { \n" + " this.wsInstance.close(); \n" + " } \n" + " }; \n" + " var heartBeatStart = false; \n" + " function checkLastRegTime() { \n" + " var now = new Date().valueOf(); \n" + " var TimeGap = now - LastRegTime; \n" + " if (TimeGap > 5000 && !heartBeatStart) { \n" + " HeartBeat(); \n" + " heartBeatStart = true; \n" + " } \n" + " } \n" + " var ws = null \n" + " function HeartBeat() { \n" + " var heartBeatItem = function () { \n" + " if(ws !== null) { \n" + " ws.send(JSON.stringify(paramStr)); \n" + " return; \n" + " } \n" + " ws = new getWebsocketObj(); \n" + " ws.onmessage = function () { \n" + " self.setTimeout(function() { \n" + " ws.send(JSON.stringify(paramStr)) \n" + " }, 5000); \n" + " }; \n" + " ws.onclose = function () { \n" + " ws = null; \n" + " self.setTimeout(heartBeatItem, 5000); \n" + " }; \n" + " ws.connect('ws://127.0.0.1:58892/askwebnotify'); \n" + " ws.onopen = function () { \n" + " ws.send(JSON.stringify(paramStr)); \n" + " }; \n" + " }; \n" + " heartBeatItem(); \n" + " }; \n" + " var paramStr; \n" + " var startCheck = false; \n" + " self.addEventListener( \n" + " 'message', \n" + " function (event) { \n" + " var data = event.data; \n" + " paramStr = data.param; \n" + " paramStr.heartBeat = true; \n" + " LastRegTime = data.LastRegTime; \n" + " if (!startCheck) { \n" + " startCheck = true; \n" + " self.setInterval(checkLastRegTime, 5000); \n" + " } \n" + " }, \n" + " false \n" + " ); \n" /** * 生成guid的接口 * @returns guid */ function guid() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); } /** * 开启多用户的接口 */ var serverId = undefined function EnableMultiUser() { serverId = getServerId(); InitSdk(true) } /** * 自定义协议启动服务端 * 默认不带参数serverId,linux未升级之前不要使用多用户 */ function InitWpsCloudSvr() { if (serverId == undefined) window.location.href = "ksoWPSCloudSvr://start=RelayHttpServer"//是否启动wps弹框 else window.location.href = "ksoWPSCloudSvr://start=RelayHttpServer" + "&serverId=" + serverId //是否启动wps弹框 } /** * 获取serverId的接口 * @returns serverId */ function getServerId() { if (window.localStorage) { if (localStorage.getItem("serverId")) { // } else { localStorage.setItem("serverId", guid()); } return localStorage.getItem("serverId"); } else { return guid(); } } /** * 将字符串转成二进制,这里用来将字符串化后的js代码转成二进制文件 * @param {*} code * @returns js文件对象的url */ function codeToBlob(code) { var blob = new Blob([code], { type: 'text/javascript' }); // 生成js文件对象 var objectURL = window.URL.createObjectURL(blob); // 生成js文件的url return objectURL; } var RegWebNotifyMap = { wps: {}, wpp: {}, et: {}, pdf: {} } var bWebNotifyUseTimeout = true function WebNotifyUseTimeout(value) { bWebNotifyUseTimeout = value ? true : false } var g_businessId = Number(Math.random().toString().substr(3, 5) + Date.parse(new Date())).toString(36); var HeartBeatWorker var checkVersionInterval if (window.Worker) { try { var code = ''; HeartBeatWorkerCallBack() checkVersionInterval = setInterval(HeartBeatWorkerCallBack,1000) } catch (error) { // } } function HeartBeatWorkerCallBack(){ if(serverVersion === 'wait'){ return; } if(isReplaceWebSocket()) { code = HeartBeatCodeWebSocket; } else { code = HeartBeatCode }; HeartBeatWorker = new Worker(codeToBlob(code)); if(checkVersionInterval) { clearInterval(checkVersionInterval); } return; } var g_LastRegTime; /** * 注册一个前端页面接收WPS传来消息的方法 * @param {*} clientType wps | et | wpp * @param {*} name WPS加载项的名称 * @param {*} callBack 回调函数 * @param {*} wpsclient wpsclient对象 */ function RegWebNotify(clientType, name, callBack, wpsclient) { if (clientType != "wps" && clientType != "wpp" && clientType != "et" && clientType != "pdf") return; var paramStr = {} if (wpsclient) { if (wpsclient.notifyRegsitered == true) { return } wpsclient.notifyRegsitered = true; paramStr = { clientId: wpsclient.clientId, name: name, type: clientType, serverId: serverId } } else { if (typeof callBack != 'function') return if (RegWebNotifyMap[clientType][name]) { RegWebNotifyMap[clientType][name] = callBack; return } var RegWebNotifyID = new Date().valueOf() + '' paramStr = { id: RegWebNotifyID, name: name, type: clientType, serverId: serverId } RegWebNotifyMap[clientType][name] = callBack } var askItem = function () { var xhr = getHttpObj() xhr.onload = function (e) { if(!WpsInvoke.RegWebNotifyEnable){ RegWebNotifyMap[clientType][name]=null; return ; } if (xhr.responseText == "WPSInnerMessage_quit" || (xhr.status != undefined && xhr.status != 200)||!WpsInvoke.RegWebNotifyEnable) { if ((!wpsclient || wpsclient.single)) { window.setTimeout(askItem, 2000); } return; } window.setTimeout(askItem, 300) // fix 新版本客户端使用旧版sdk的时候,会出现版本号判断问题 if (serverVersion!== "" && serverVersion !== "wait") { try { if (!HeartBeatWorker) throw new Error(); var resText = JSON.parse(xhr.responseText); paramStr.messageId = resText.msgId; if (wpsclient) { if (resText.data != undefined && paramStr.messageId != undefined) // 如果发的数据是字符串化后的json对象,这里的resText.data就是一个json对象,可以输出自己想要的json数据 if (typeof resText.data == 'object') wpsclient.OnRegWebNotify(JSON.stringify(resText.data)) else wpsclient.OnRegWebNotify(resText.data) else wpsclient.OnRegWebNotify(xhr.responseText) } else { var func = RegWebNotifyMap[clientType][name] if (resText.data != undefined && paramStr.messageId != undefined) // 如果发的数据是字符串化后的json对象,这里的resText.data就是一个json对象,可以输出自己想要的json数据 if (typeof resText.data == 'object') func(JSON.stringify(resText.data)) else func(resText.data) else func(xhr.responseText) } } catch (e) { // 这里做一个容错,即使json解析失败,也要把msgId提取出来,发回给服务端,避免消息清不掉一直重复发送 // 同时把data也取出来,但是格式无法保证 var data var str = xhr.responseText var idx1 = str.indexOf("\"msgId\"") var idx2 var idx3 var idx4 var data if (idx1 != -1) { idx1 = idx1 + 8 idx2 = str.indexOf("\"data\"") - 2 paramStr.messageId = parseInt(str.substring(idx1, idx2)) idx3 = str.indexOf("\"data\"") + 8 idx4 = str.length - 2 data = str.substring(idx3, idx4) } if (wpsclient) { if (paramStr.messageId !== undefined && data != undefined) wpsclient.OnRegWebNotify(data) else wpsclient.OnRegWebNotify(xhr.responseText) } else { var func = RegWebNotifyMap[clientType][name] if (paramStr.messageId !== undefined && data != undefined) func(data) else func(xhr.responseText) } } } else { var resText = JSON.parse(xhr.responseText); paramStr.messageId = resText.msgId; var resData = decode(resText.data); if (wpsclient) { wpsclient.OnRegWebNotify(resData) } else { var func = RegWebNotifyMap[clientType][name] func(resData) } } } xhr.onerror = function (e) { if (bWebNotifyUseTimeout) window.setTimeout(askItem, 1000) else window.setTimeout(askItem, 10000) } xhr.ontimeout = function (e) { if (bWebNotifyUseTimeout) window.setTimeout(askItem, 300) else window.setTimeout(askItem, 10000) } if (IEVersion() < 10) { xhr.onreadystatechange = function () { if (xhr.readyState != 4) return; if (xhr.bTimeout) { return; } if (xhr.status === 200) xhr.onload(); else xhr.onerror(); } } xhr.open('POST', GetUrlBase() + '/askwebnotify', true) if (bWebNotifyUseTimeout) xhr.timeout = 2000; if (HeartBeatWorker) { g_LastRegTime = new Date().valueOf(); var param = { param: { name: name, type: clientType, businessId: g_businessId, serverId: serverId }, LastRegTime: g_LastRegTime } HeartBeatWorker.postMessage(param) } if (HeartBeatWorker) { paramStr.businessId = g_businessId } xhr.send(JSON.stringify(paramStr)); } // 用途ws发送消失后,客户端一段时间没有回复,自动关闭链接操作 var askItemWebsocketTimer = null; // 客户端有消息推送标记 var hasResponse = false; // 客户端无消息推送标记 var isTimeout = false; var askItemWebsocket = function() { if(!isReplaceWebSocket()) { askItem(); return } var ws = new getWebsocketObj(); ws.connect(GetUrlBase() + '/askwebnotify'); ws.onmessage = function(res){ hasResponse = true; ws.close(); if(askItemWebsocketTimer !== null){ clearTimeout(askItemWebsocketTimer); askItemWebsocketTimer = null; } if(!WpsInvoke.RegWebNotifyEnable){ RegWebNotifyMap[clientType][name]=null; return ; } if (res.data == "WPSInnerMessage_quit" || httpCodeErrorMessageList.indexOf(res.data) != -1 ||!WpsInvoke.RegWebNotifyEnable ) { if ((!wpsclient || wpsclient.single)) { window.setTimeout(function() { askItemWebsocket(); }, 2000); } return; }; window.setTimeout(function() { askItemWebsocket(); }, 300); // fix 新版本客户端使用旧版sdk的时候,会出现版本号判断问题 if (serverVersion!== "" && serverVersion !== "wait") { try { if (!HeartBeatWorker) throw new Error(); var resText = JSON.parse(res.data); paramStr.messageId = resText.msgId; if (wpsclient) { if (resText.data != undefined && paramStr.messageId != undefined) // 如果发的数据是字符串化后的json对象,这里的resText.data就是一个json对象,可以输出自己想要的json数据 if (typeof resText.data == 'object') wpsclient.OnRegWebNotify(JSON.stringify(resText.data)) else wpsclient.OnRegWebNotify(resText.data) else wpsclient.OnRegWebNotify(res.data) } else { var func = RegWebNotifyMap[clientType][name] if (resText.data != undefined && paramStr.messageId != undefined) // 如果发的数据是字符串化后的json对象,这里的resText.data就是一个json对象,可以输出自己想要的json数据 if (typeof resText.data == 'object') func(JSON.stringify(resText.data)) else func(resText.data) else func(res.data) } } catch (e) { // 这里做一个容错,即使json解析失败,也要把msgId提取出来,发回给服务端,避免消息清不掉一直重复发送 // 同时把data也取出来,但是格式无法保证 var data var str = res.data var idx1 = str.indexOf("\"msgId\"") var idx2 var idx3 var idx4 var data if (idx1 != -1) { idx1 = idx1 + 8 idx2 = str.indexOf("\"data\"") - 2 paramStr.messageId = parseInt(str.substring(idx1, idx2)) idx3 = str.indexOf("\"data\"") + 8 idx4 = str.length - 2 data = str.substring(idx3, idx4) } if (wpsclient) { if (paramStr.messageId !== undefined && data != undefined) wpsclient.OnRegWebNotify(data) else wpsclient.OnRegWebNotify(res.data) } else { var func = RegWebNotifyMap[clientType][name] if (paramStr.messageId !== undefined && data != undefined) func(data) else func(res.data) } } } else { var resText = res.data; paramStr.messageId = resText.msgId; var resData = decode(resText.data); if (wpsclient) { wpsclient.OnRegWebNotify(resData) } else { var func = RegWebNotifyMap[clientType][name] func(resData) } } }; ws.onclose = function (e) { // 正常有请求响应,不做处理由onmessage进行递归 if(hasResponse === true){ hasResponse = false; return }; // 超时处理 if(isTimeout === true) { isTimeout = false; if (bWebNotifyUseTimeout) window.setTimeout(askItemWebsocket, 300); else window.setTimeout(askItemWebsocket, 10000); return }; // 异常处理 if (bWebNotifyUseTimeout) window.setTimeout(askItemWebsocket, 1000); else window.setTimeout(askItemWebsocket, 10000); } ws.onopen = function(){ if (HeartBeatWorker) { paramStr.businessId = g_businessId } ws.send(JSON.stringify(paramStr)); askItemWebsocketTimer = window.setTimeout(function() { isTimeout = true; ws.close(); askItemWebsocketTimer = null; }, 2000); }; if (HeartBeatWorker) { g_LastRegTime = new Date().valueOf(); var param = { param: { name: name, type: clientType, businessId: g_businessId, serverId: serverId }, LastRegTime: g_LastRegTime } HeartBeatWorker.postMessage(param) } }; if(isReplaceWebSocket()) { askItemWebsocket(); } else { askItem(); } } /** * 获取服务端版本号的接口,这里主要是初始化一些参数 * @param {*} clientType 加载项类型, wps / wpp / et * @param {*} name 加载项名称 * @param {*} func 客户端加载项要执行的方法 * @param {*} param 客户端加载项执行方法的参数 * @param {*} callBack 回调函数 * @param {*} showToFront 设置客户端是否显示到前面 * @param {*} jsPluginsXml 设置加载项路径 * @param {*} silentMode 是否是静默启动 * @param {*} timeout 设置客户端启动超时时间(透传客户端内部执行),单位为ms * @param {*} startparam 传递给wps客户端的启动参数 */ function WpsStartWrapVersion(clientType, name, func, param, callBack, showToFront, jsPluginsXml, silentMode, timeout, startparam) { var paramEx = { jsPluginsXml: jsPluginsXml ? jsPluginsXml : "", showToFront: typeof (showToFront) == 'boolean' ? showToFront : true, param: (typeof (param) == 'object' ? param : JSON.parse(param)) } var options = { clientType: clientType, name: name, func: func, param: paramEx, urlBase: GetUrlBase(), callBack: callBack, wpsclient: undefined, concurrent: true, silentMode: silentMode, timeout: timeout, startparam: startparam, } WpsStartWrapVersionInner(options); } //从外部浏览器远程调用 WPS 加载项中的方法 var WpsInvoke = { InvokeAsHttp: WpsStartWrapVersion, InvokeAsHttps: WpsStartWrapVersion, RegWebNotify: RegWebNotify, ClientType: { wps: "wps", et: "et", wpp: "wpp", pdf: "pdf" }, CreateXHR: getHttpObj, IsClientRunning: IsClientRunning, GetVersion: GetVersion, RegWebNotifyEnable:true } /** * @constructor WpsClient wps客户端 * @param {string} clientType 必传参数,加载项类型,有效值为"wps","wpp","et";分别表示文字,演示,电子表格 */ function WpsClient(clientType) { /** * 设置RegWebNotify的回调函数,加载项给业务端发消息通过该函数 * @memberof WpsClient * @member onMessage */ this.onMessage; /** * 设置加载项路径 * @memberof WpsClient * @member jsPluginsXml */ this.jsPluginsXml; /** * 内部成员,外部无需调用 */ this.notifyRegsitered = false; this.clientId = ""; this.concurrent = true; this.clientType = clientType; /** * 内部函数,外部无需调用 * @param {*} options */ this.initWpsClient = function (options) { options.clientType = this.clientType options.wpsclient = this options.concurrent = this.concurrent WpsStartWrapVersionInner(options) } /** * 以http启动 * @param {string} name 加载项名称 * @param {string} func 要调用的加载项中的函数行 * @param {string} param 在加载项中执行函数func要传递的数据 * @param {function({int, string})} callBack 回调函数,status = 0 表示成功,失败请查看message信息 * @param {bool} showToFront 设置wps是否显示到前面来 * @param {*} timeout 设置客户端启动超时时间(透传客户端内部执行),单位为ms * @param {*} startparam 传递给wps客户端的启动参数 * @return {string} "Failed to send message to WPS." 发送消息失败,客户端已关闭; * "WPS Addon is not response." 加载项阻塞,函数执行失败 */ this.InvokeAsHttp = function (name, func, param, callBack, showToFront, timeout, startparam) { function clientCallback(res) { //this不是WpsClient,是options对象 if (res.status !== 0 || serverVersion < "1.0.1" || this.wpsclient.single == true) { if (callBack) callBack(res); if (serverVersion < "1.0.1" || this.wpsclient.single == true) RegWebNotify(clientType, name, this.wpsclient.onMessage) return; } // fix 新版本客户端使用旧版sdk的时候,会出现版本号判断问题 if (serverVersion!== "" && serverVersion !== "wait") { try { var resObject = JSON.parse(res.response); if (this.wpsclient.clientId == "") { this.wpsclient.clientId = resObject.clientId; } if (typeof resObject.data == "object") res.response = JSON.stringify(resObject.data); else res.response = resObject.data; } catch (e) { var str = res.response var idx1 = str.indexOf("\"clientId\":\"{") var idx2 var idx3 var idx4 if (idx1 != -1) { idx1 = idx1 + ("\"clientId\":\"{").length - 1 idx2 = str.indexOf("\"data\":") - 3 if (this.wpsclient.clientId == "") { this.wpsclient.clientId = str.substring(idx1, idx2); } idx3 = str.indexOf("\"data\":") + ("\"data\":").length idx4 = str.length - 1 if (idx3 < idx4) res.response = str.substring(idx3, idx4) else res.response = ""; } } } else { var resObject = JSON.parse(res.response); if (this.wpsclient.clientId == "") { this.wpsclient.clientId = resObject.clientId; } res.response = decode(resObject.data); } if (IEVersion() < 10) eval(" res.response = '" + res.response + "';"); if (callBack) callBack(res); this.wpsclient.RegWebNotify(name); } var paramEx = { jsPluginsXml: this.jsPluginsXml ? this.jsPluginsXml : "", showToFront: typeof (showToFront) == 'boolean' ? showToFront : true, param: (typeof (param) == 'object' ? param : JSON.parse(param)) } this.initWpsClient({ name: name, func: func, param: paramEx, urlBase: GetUrlBase(), callBack: clientCallback, timeout: timeout, startparam: startparam, }) } /** * 以https启动 * @param {string} name 加载项名称 * @param {string} func 要调用的加载项中的函数行 * @param {string} param 在加载项中执行函数func要传递的数据 * @param {function({int, string})} callBack 回调函数,status = 0 表示成功,失败请查看message信息 * @param {*} timeout 设置客户端启动超时时间(透传客户端内部执行),单位为ms * @param {*} startparam 传递给wps客户端的启动参数 * @param {bool} showToFront 设置wps是否显示到前面来 */ this.InvokeAsHttps = function (name, func, param, callBack, showToFront, timeout, startparam) { var paramEx = { jsPluginsXml: this.jsPluginsXml ? this.jsPluginsXml : "", showToFront: typeof (showToFront) == 'boolean' ? showToFront : true, param: (typeof (param) == 'object' ? param : JSON.parse(param)) } this.initWpsClient({ name: name, func: func, param: paramEx, urlBase: GetUrlBase(), callBack: callBack, timeout: timeout, startparam: startparam, }) } /** * 内部函数,外部无需调用 * @param {*} name */ this.RegWebNotify = function (name) { RegWebNotify(this.clientType, name, null, this); } /** * 消息注册函数的回调函数 * @param {*} message 客户端发来的消息 */ this.OnRegWebNotify = function (message) { if (this.onMessage) this.onMessage(message) } /** * 以静默模式启动客户端 * @param {string} name 必传参数,加载项名称 * @param {*} timeout 设置客户端启动超时时间(透传客户端内部执行),单位为ms * @param {*} startparam 传递给wps客户端的启动参数 * @param {function({int, string})} [callBack] 回调函数,status = 0 表示成功,失败请查看message信息 */ this.StartWpsInSilentMode = function (name, callBack, timeout, startparam) { function initCallback(res) { //this不是WpsClient,是options对象 if (res.status !== 0 || serverVersion < "1.0.1" || this.wpsclient.single == true) { if (callBack) callBack(res); if (serverVersion < "1.0.1" || this.wpsclient.single == true) RegWebNotify(clientType, name, this.wpsclient.onMessage) return; } var jsonObj = JSON.parse(res.response); if (this.wpsclient.clientId == "") { this.wpsclient.clientId = jsonObj.clientId; } // fix 新版本客户端使用旧版sdk的时候,会出现版本号判断问题 if (serverVersion!== "" && serverVersion !== "wait") { res.response = JSON.stringify(jsonObj.data); } else { res.response = decode(jsonObj.data); } if (callBack) { callBack(res); } this.wpsclient.RegWebNotify(name); } var paramEx = { jsPluginsXml: this.jsPluginsXml, showToFront: false, param: { status: "InitInSilentMode" } } this.silentMode = true; this.initWpsClient({ name: name, func: "", param: paramEx, urlBase: GetUrlBase(), callBack: initCallback, timeout: timeout, startparam: startparam, }) } /** * 显示客户端到最前面 * @param {string} name 必传参数,加载项名称 * @param {function({int, string})} [callBack] 回调函数 */ this.ShowToFront = function (name, callBack) { if (serverVersion < "1.0.1") { if (callBack) { callBack({ status: 4, message: "当前客户端不支持,请升级客户端" }); return; } return; } if (this.clientId == "") { if (callBack) callBack({ status: 3, message: "没有静默启动客户端" }); return; } var paramEx = { jsPluginsXml: "", showToFront: true, param: { status: "ShowToFront" } } this.initWpsClient({ name: name, func: "", param: paramEx, urlBase: GetUrlBase(), callBack: callBack }) } /** * 关闭未显示出来的静默启动客户端 * @param {string} name 必传参数,加载项名称 * @param {function({int, string})} [callBack] 回调函数 */ this.CloseSilentClient = function (name, callBack) { if (serverVersion < "1.0.1") { if (callBack) { callBack({ status: 4, message: "当前客户端不支持,请升级客户端" }); return; } return; } if (this.clientId == "") { if (callBack) callBack({ status: 3, message: "没有静默启动客户端" }); return; } var paramEx = { jsPluginsXml: "", showToFront: false, param: undefined } var func; if (this.clientType == "wps") func = "wps.WpsApplication().Quit" else if (this.clientType == "et") func = "wps.EtApplication().Quit" else if (this.clientType == "wpp") func = "wps.WppApplication().Quit" function closeSilentClient(res) { if (res.status == 0) this.wpsclient.clientId = "" if (callBack) callBack(res); return; } this.initWpsClient({ name: name, func: func, param: paramEx, urlBase: GetUrlBase(), callBack: closeSilentClient }) } /** * 当前客户端是否在运行,使用WpsClient.IsClientRunning()进行调用 * @param {function({int, string})} [callBack] 回调函数,"Client is running." 客户端正在运行 * "Client is not running." 客户端没有运行 */ this.IsClientRunning = function (callBack) { if (serverVersion < "1.0.1") { if (callBack) { callBack({ status: 4, message: "当前客户端不支持,请升级客户端" }); return; } return; } IsClientRunning(this.clientType, callBack, this) } } /** * 初始化sdk,用来减少在服务进程启动时自定义协议弹框出现的次数 */ var g_isSdkInited = false; function InitSdk(bMultiUser) { g_isSdkInited = false; var url = GetUrlBase() + "/version"; startWps({ url: url, sendData: JSON.stringify({ serverId: serverId }), callBack: function (res) { if ((!serverId && !bMultiUser) || bMultiUser) g_isSdkInited = true; if (res.status !== 0 && res.message !== "Subserver not available.") { serverVersion = "wait" return; } if (res.response && serverVersion == "wait"){ serverVersion = res.response; sessionStorage.setItem('serverVersion', serverVersion); } }, tryCount: 1, bPop: false, concurrent: true, timeout: 1000 }); } InitSdk(false); function GetVersion(callBack) { var url = GetUrlBase() + "/version"; startWps({ url: url, data: "", callBack: function (res) { callBack && callBack(res); if (res.status !== 0 && res.message !== "Subserver not available.") { serverVersion = "wait" return; } if (res.response && serverVersion == "wait"){ serverVersion = res.response; sessionStorage.setItem('serverVersion', serverVersion); } }, tryCount: 4, bPop: true, timeout: 5000 }); } if (typeof noGlobal === "undefined") { window.WpsInvoke = WpsInvoke; window.WpsClient = WpsClient; window.WebNotifyUseTimeout = WebNotifyUseTimeout; window.EnableMultiUser = EnableMultiUser; } /** * 当前客户端是否在运行,使用WpsInvoke.IsClientRunning()进行调用 * @param {string} clientType 加载项类型 * @param {function} [callBack] 回调函数,"Client is running." 客户端正在运行 * "Client is not running." 客户端没有运行 */ function IsClientRunning(clientType, callBack, wpsclient) { var url = GetUrlBase() + "/isRunning"; var wrapper = { id: wpsclient == undefined ? undefined : wpsclient.clientId, app: clientType, serverId: serverId } wrapper = JSON.stringify(wrapper); startWps({ url: url, sendData: wrapper, callBack: callBack, tryCount: 1, bPop: false, timeout: 2000, concurrent: true, wpsclient: wpsclient }); } /** * 获取publish.xml的内容 * @param {*} callBack 回调函数 */ function WpsAddonGetAllConfigInner(callBack) { var options = { url: GetUrlBase() + "/publishlist", type: "POST", sendData: JSON.stringify({ serverId: serverId }), callBack: callBack, tryCount: 3, bPop: true, timeout: 5000, concurrent: true, } startWps(options); } /** * 先获取一下版本号 * @param {*} callBack 回调函数 */ function WpsAddonGetAllConfig(callBack) { var options = { callBack: callBack, isPublish: true, urlBase: GetUrlBase() } WpsStartWrapVersionInner(options); } /** * 检查ribbon.xml文件是否有效 * @param {*} element 参数对象 * @param {*} callBack 回调函数 */ function WpsAddonVerifyStatus(element, callBack) { var xmlReq = getHttpObj(); var offline = element.online === "false"; var url = offline ? element.url : element.url + "ribbon.xml"; xmlReq.open("POST", GetUrlBase() + "/redirect/runParams"); xmlReq.onload = function (res) { if (offline && !res.target.response.startsWith("7z")) { callBack({ status: 1, msg: "不是有效的7z格式" + url }); } else if (!offline && !res.target.response.startsWith("= "1.0.2" && serverId != undefined) { var base64Data = encode(strData); return JSON.stringify({ serverId: serverId, data: base64Data }) } else { return encode(strData); } } var verifyStatus = function(){}; if(isReplaceWebSocket()) { verifyStatus = WpsAddonVerifyStatusWebSocket } else { verifyStatus = WpsAddonVerifyStatus } //管理 WPS 加载项 var WpsAddonMgr = { getAllConfig: WpsAddonGetAllConfig, verifyStatus: verifyStatus, enable: WpsAddonEnable, disable: WpsAddonDisable, disableall: WpsAddonDisableAll } if (typeof noGlobal === "undefined") { window.WpsAddonMgr = WpsAddonMgr; } return { WpsInvoke: WpsInvoke, WpsClient: WpsClient, WebNotifyUseTimeout: WebNotifyUseTimeout, EnableMultiUser: EnableMultiUser, WpsAddonMgr: WpsAddonMgr, version: "1.0.33" }; }); /** * 改动时间:2022-11-28 19:06 * 改动说明:1、调整心跳触发时机,确认云服务版本号后才触发 * 2、轮询客户端消息赋予businessId调整至请求发送前。避免心跳没创建的异常情况 * 改动影响:http&ws下,心跳触发是否正常 */