/* jsonrpc-2.0 over http mode:async exp: by:liangliangit v2.0 beta 2.0 beta功能 新增send方法 建议用send方法替代call方法 新增错误码订阅事件委托 例如可以订阅一份账户未登录的错误通知信息,然后处理用户跳转到登录页面,而不需要每次都判断请求是否未授权 新增日志打印开启,关闭功能,默认开启 */ const jsonrpc={ //会话 _session:{ key:localStorage.getItem("jsonrpc_session_key") }, //错误信息订阅通知 (例如可以订阅一份账户未登录的错误通知信息,然后处理用户跳转到登录页面) errnotifys:new Map(), //返回订阅id便于取消订阅 errNotifyAdd:function(errcode,callback){ let callfuncs = this.errnotifys.get(errcode) if (callfuncs == null || callfuncs == undefined || callfuncs == ""){ let funcs = [] funcs.push(callback) this.errnotifys.set(errcode,funcs) return 0 } let index = callfuncs.length callfuncs[index]=callback this.errnotifys.set(errcode,callfuncs) return index }, errNotifyDel:function(errcode,id){ let callfuncs = this.errnotifys.get(errcode) if (callfuncs == null || callfuncs == undefined || callfuncs == ""){ return } callfuncs.delete(id) this.errnotifys.set(errcode,callfuncs) }, _errNotify:function(errcode){ let callfuncs = this.errnotifys.get(errcode) if (callfuncs == null || callfuncs == undefined || callfuncs == ""){ return } for(let func in callfuncs){ callfuncs[func]() } }, strict:true, log:false, jsonRequestCode:{ jsonrpc:"2.0", method:"", params:{}, id:"", timestampin:"", }, jsonResponseCode:{ jsonrpc:"2.0", result:{}, id:"", timestampin:"", timestampout:"", error:{ message:"", code:"", data:"" }, }, setSessionKey:function(key){ localStorage.setItem("jsonrpc_session_key",key) this._session.key = key }, setUrl:function(url){ localStorage.setItem("jsonrpc_url",url) }, send:function(url,rpcRequest,callback,errorcall){ let guid = this.guid() rpcRequest.id=guid rpcRequest.jsonrpc = "2.0" rpcRequest.session = this._session.key let now = new Date().getTime() rpcRequest.timestampin=now.toString() let jsonString = JSON.stringify(rpcRequest) if (this.log){console.log("rpcCall to service:"+url);console.log(jsonString)} let jsonrpc = this this.asyncpost(url,jsonString).then( rpcResponse=>{ if (jsonrpc.log){console.log(rpcResponse)} if(!rpcResponse){ this._onError("收到了错误的响应:无法解析json字符串") if (typeof (errorcall) == "function"){ let error={ message:"收到了错误的响应:无法解析json字符串", code:-1, data:{} } errorcall(error) } return } if(this.strict){ if(rpcResponse.id == "" || rpcResponse.id == undefined){ this._onError("收到了错误的响应:无法解析response.id,id为必须参数") if (typeof (errorcall) == "function"){ let error={ message:"收到了错误的响应:无法解析response.id,id为必须参数", code:-1, data:{} } errorcall(error) } return } if(rpcResponse.jsonrpc != "2.0"){ this._onError("收到了错误的响应:无法解析JSON-RPC,jsonrpc参数必须为2.0") if (typeof (errorcall) == "function"){ let error={ message:"收到了错误的响应:无法解析JSON-RPC,jsonrpc参数必须为2.0", code:-1, data:{} } errorcall(error) } return } if(rpcResponse.error.code != 200){ //this._onError(rpcResponse.error) if (typeof (errorcall) == "function"){ errorcall(rpcResponse.error) } jsonrpc._errNotify(rpcResponse.error.code) return } } callback(rpcResponse) } ) }, //input jsonrpc.request //return jsonrpc.response.result result:function(url,rpcRequest){ let guid = this.guid() rpcRequest.id=guid rpcRequest.jsonrpc = "2.0" rpcRequest.session = this._session.key let now = new Date().getTime() rpcRequest.timestampin=now.toString() let jsonString = JSON.stringify(rpcRequest) if (this.log){console.log("rpcCall to service:"+url);console.log(jsonString)} let jsonrpc = this return new Promise(function(resolve, reject) { jsonrpc.asyncpost(url,jsonString).then( rpcResponse=>{ if (jsonrpc.log){console.log(rpcResponse)} if(!rpcResponse){ jsonrpc._onError("收到了错误的响应:无法解析json字符串") let error={ message:"收到了错误的响应:无法解析json字符串", code:-1, data:{} } reject(error) return } if(jsonrpc.strict){ if(rpcResponse.id == "" || rpcResponse.id == undefined){ jsonrpc._onError("收到了错误的响应:无法解析response.id,id为必须参数") let error={ message:"收到了错误的响应:无法解析response.id,id为必须参数", code:-1, data:{} } reject(error) return } if(rpcResponse.jsonrpc != "2.0"){ jsonrpc._onError("收到了错误的响应:无法解析JSON-RPC,jsonrpc参数必须为2.0") let error={ message:"收到了错误的响应:无法解析JSON-RPC,jsonrpc参数必须为2.0", code:-1, data:{} } reject(error) return } if(rpcResponse.error.code != 200){ jsonrpc._errNotify(rpcResponse.error.code) reject(rpcResponse.error) return } } resolve(rpcResponse.result) } ) }) }, fetch:function(url,rpcRequest){ let guid = this.guid() rpcRequest.id=guid rpcRequest.jsonrpc = "2.0" rpcRequest.session = this._session.key let now = new Date().getTime() rpcRequest.timestampin=now.toString() let jsonString = JSON.stringify(rpcRequest) if (this.log){console.log("rpcCall to service:"+url);console.log(jsonString)} let jsonrpc = this return new Promise(function(resolve, reject) { jsonrpc.asyncpost(url,jsonString).then( rpcResponse=>{ if (jsonrpc.log){console.log(rpcResponse)} if(!rpcResponse){ jsonrpc._onError("收到了错误的响应:无法解析json字符串") let error={ message:"收到了错误的响应:无法解析json字符串", code:-1, data:{} } reject(error) return } if(jsonrpc.strict){ if(rpcResponse.id == "" || rpcResponse.id == undefined){ jsonrpc._onError("收到了错误的响应:无法解析response.id,id为必须参数") let error={ message:"收到了错误的响应:无法解析response.id,id为必须参数", code:-1, data:{} } reject(error) return } if(rpcResponse.jsonrpc != "2.0"){ jsonrpc._onError("收到了错误的响应:无法解析JSON-RPC,jsonrpc参数必须为2.0") let error={ message:"收到了错误的响应:无法解析JSON-RPC,jsonrpc参数必须为2.0", code:-1, data:{} } reject(error) return } if(rpcResponse.error.code != 200){ jsonrpc._errNotify(rpcResponse.error.code) reject(rpcResponse.error) return } } resolve(rpcResponse.result) } ) }) }, //生成guid guid:function() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { let r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8) return v.toString(16) }) }, _onHttpError:function(err){ this.onHttpError(err) }, onHttpError:function(err){}, _onError:function(err){ this.onError(err) }, onError:function(err){}, asyncpost:function(url,jsonString){ let r = fetch(url, { method: 'POST', // or 'PUT' mode: 'cors', headers: { 'Content-Type': 'application/json', }, body: jsonString } ).then(response => { if(response.status != 200){ this._onHttpError(response.error) let rpcResponse={ jsonrpc:"2.0", id:"1", error:{ message:"http响应错误:"+response.status, code:-1 } } return rpcResponse } return response.json() }).catch(response => { this._onHttpError(response) let rpcResponse={ jsonrpc:"2.0", id:"1", error:{ message:"网路连接失败,请重试", code:-1 } } return rpcResponse }) return r }, } export default jsonrpc