| 谢谢啦 |
引用:JackJiang 发表于 2019-07-20 16:28 群主一如既往的认真回复,佩服 |
|
QQ上已经回复你了,我把回复也贴到这里,方便其他人看到。 你的这段JS,其它内容基本没问题,主要是newData的拼接,注意不能用复合对象,而应该是文本,你应该把对象通过JSON.stringify(obj)转pb字符串后,再传入。 之所以这么做,原因是像ios等这种语言里没有很强的JSON解析工具,它们的嵌套JSON对象的解析能力太弱,所以就这样设计了,目的是为了降低客户端的解析难度,以便更多不同语或技术的客户端可以使用这些接口,就是这样。 以下代码是RainbowChat-Web产品中的实现代码,你可以参考一下,一定能解决你的疑问: /**
* 一个通用的RainbowChat-Web http rest接口请求和处理实用方法(本方法使用JSONP方式,可完美支持任何跨域调用问题)。
* <p>
* 本方法调用的是基于jQuery-jsonp库,实现了jQuery无法解决跨域调用时的异常处理问题(jQuery中无法捕获跨域调用时出现的异常)。
* </p>
* <p>
* 本方接口的返回值字段定义以http rest服务端框架中的相关定义为准,请务必与其保持一致。
* </p>
*
* @param processorId、jobDispatchId、actionId、newDataObj、oldDataObj 详见http rest接口报务端的接口处理逻辑(即http MVC框架原理)
* @param logTag log标签(仅用于log的输出),非必须参数
* @param fnForSucess 接口成功调用完成后的回调函数
* @param fnForFail 接口调用失败后的回调函数
* @param isShowLoadingToast true表示在进行网络请求时会自动显示一个“载入中”的Toast,并在请求完成或出错时取消显示
*/
var _jsonpFromHttpRestServer = function (processorId, jobDispatchId, actionId
, newDataObj, oldDataObj, logTag, fnForSucess, fnForFail, isShowLoadingToast) {
// 打印rest接口的编号,方便与服务端的接口调试
var printRestNum = function(processorId, jobDispatchId, actionId) {
var ret = "";
if(processorId > 0)
ret += processorId;
if(jobDispatchId > 0)
ret += "-"+jobDispatchId;
if(actionId > 0)
ret += "-"+actionId;
return ret;
};
var REST_NUM_STR = '接口'+printRestNum(processorId, jobDispatchId, actionId)+'→';
// 【newData字段内容准备】
// (如果此字段内容是对象则要转JSON字串并进行url encode,否帖如存在特殊符号http get会出问题的——这是常识)
var newDataJSON = newDataObj;
var newDataJSONAfterEncode = null;
if (newDataObj && !RBChatUtils.isString(newDataObj)) {
newDataJSON = JSON.stringify(newDataObj);
}
if (newDataJSON) {
newDataJSONAfterEncode = encodeURIComponent(newDataJSON);// encodeURIComponent也会自动对包括html的格式字符在内的相关字符进行转义处理
}
// 【oldData字段内容准备】
// (如果此字段内容是对象则要转JSON字串并进行url encode ,否帖如存在特殊符号http get会出问题的——这是常识)
var oldDataJSON = oldDataObj;
var oldDataJSONAfterEncode = null;
if (oldDataObj && !RBChatUtils.isString(oldDataObj)) {
oldDataJSON = JSON.stringify(oldDataObj);
}
if (oldDataJSON) {
oldDataJSONAfterEncode = encodeURIComponent(oldDataJSON);
}
RBChatUtils.logToConsole('[AJAX/JSONP-『'+REST_NUM_STR+ logTag + '』准备➊] 马上调用接口,调用时传递的参数为:'
+ 'processorId=' + processorId + ', jobDispatchId=' + jobDispatchId + ', actionId=' + actionId
+ ', newDataJSON=' + newDataJSON + ', oldDataJSON=' + oldDataJSON
+ ', newDataJSONAfterEncode=' + newDataJSONAfterEncode + ', oldDataJSONAfterEncode=' + oldDataJSONAfterEncode
+ ', fnForSucess is null?' + (!fnForSucess) + ', fnForFail is null?' + (!fnForFail)
);
// 显示“加载中”提示
var loadingToastId = -1;
if(isShowLoadingToast){
loadingToastId = RBChatToastHelper.showToast_Loading(null);
}
// 【开始调用HTTP REST接口】
// 注意:按照jQuery的JSONP实现,此url中的回调函数参数名必须为jsoncallback(
// jQuery将自动替换成它自已将匿名函数生成的真正回调函数名)
$.jsonp({// 注意:使用jQuery自带的$.getJSON、$.ajax等无法捕获跨域情况下的异常,JackJiang使用jquery-json库解决了这个问题
url: window.RBChatConfig.HTTP_REST_URL + '?'
+ 'processorId=' + processorId
+ '&jobDispatchId=' + jobDispatchId
+ '&actionId=' + actionId
+ '&newData=' + newDataJSONAfterEncode
+ '&uid=400069' + '&format=jsonp&jsoncallback=?&token=99999999999999'
, type: 'GET'
, cache: false
, timeout: 20000 // 设置超时20秒
, dataType: 'jsonp'
//, data: { yourdata: "data" }
//, callback: ''
, success: function (json) {
// 关闭“加载中”提示
if(isShowLoadingToast){
RBChatToastHelper.closeToast(loadingToastId);
}
//try
{
RBChatUtils.logToConsole('[AJAX/JSONP-『'+REST_NUM_STR+ logTag + '』返回➋] 服务端返回的原始json内容:' + JSON.stringify(json));
// 解析服务端返回的内容
var success = json.success;
var returnValueJSONString = json.returnValue;
// GET接口正常处理完成并返回
if (success === true) {
RBChatUtils.logToConsole('[AJAX/JSONP-『'+REST_NUM_STR+ logTag + '』解析后➌] 服务端返回的数据解析后:code='
+ success + ',returnValue=' + returnValueJSONString);
if (fnForSucess) {
fnForSucess(returnValueJSONString);
}
}
else {
// 不要用console.error,因为它会中断代码继续向下执行
console.warn('[AJAX/JSONP-『'+REST_NUM_STR+ logTag + '』解析后➌] 服务端接口处理完成,但服务端查询出错了:' + returnValueJSONString);
if (fnForFail) {
fnForFail(returnValueJSONString);
}
}
}
//catch (eex) {
// console.warn('[前端-JSONP-' + logTag + '返回➋] 处理服务端的返回结果时出错了,原因:' + JSON.stringify(eex));
// if (fnForFail) {
// fnForFail(JSON.stringify(eex));
// }
//}
}
, error: function (xhr, textStatus, errorThrown) {
// 关闭“加载中”提示
if(isShowLoadingToast){
RBChatToastHelper.closeToast(loadingToastId);
}
// 不要用console.error,因为它会中断代码继续向下执行
console.warn('[AJAX/JSONP-『'+REST_NUM_STR+ logTag + '』返回➋] $.jsonp()调用时出错了,原因:' + textStatus
+ ', 详细:' + JSON.stringify(errorThrown));
if (fnForFail) {
fnForFail(JSON.stringify(errorThrown));
}
}
});
};
/**
* 【接口1008-4-8】获取离线聊天消息的接口调用.
*
* @param user_uid 离线消息所有者的uid
* @param from_user_uid 离线消息由谁发送的uid。本参数为null表示取本地用户收到所有离线消息(不区分好友),否则表示取指定好友发过来的离线消息!
*/
submitGetOfflineChatMessagesToServer : function(user_uid, from_user_uid, fnForSucess, fnForFail) {
// 要提交给服务端的参数(详见服务端接口代码或http rest接口文档中的说明)
var m = {
'user_uid' : user_uid,
'from_user_uid' : from_user_uid
};
_jsonpFromHttpRestServer(MyProcessorConst.PROCESSOR_LOGIC, JobDispatchConst.LOGIC_GET_OFFLINE_ADD$FRIENDS$REQ, SysActionConst.ACTION_APPEND2
, JSON.stringify(m), null
, '离线消息获取接口', fnForSucess, fnForFail, true);
} |