前几天公司产品接入新的软件平台,Android app中加入我们的h5产品,接入后在软件中可直接访问html5产品。在接入的过程中,个人方面遇到些许问题,总结如下:
1、平台参数获取
进入软件后,点击进入产品页面,平台方会把用户登录初始化参数带入到产品中,如token,openid等信息,具体提取参数可以使用如下代码获取:
function GetQueryString(name)
{
var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
if (window.location == undefined)
{
if (name == "deviceUid" && cc.LOGINMAINUI_DEVICEUID)
{
return cc.LOGINMAINUI_DEVICEUID;
}
if (name == "inviteId" && cc.LOGINMAINUI_INVITEID)
{
return cc.LOGINMAINUI_INVITEID;
}
return "jelly";
}
var r = window.location.search.substr(1).match(reg);
if(r!=null)return unescape(r[2]); return null;
}
2、签名验证utf-8编码
平台签名验证中有utf-8编码处理,我搜索过很多编码,其中包括js自带方法 encodeURI(),如“至尊VIP终身卡”处理后为"%E8%87%B3%E5%B0%8AVIP%E7%BB%88%E8%BA%AB%E5%8D%A1",但平台服务器验证无法通过,后来在百度中md5加密中截取了一段关于utf-8编码的程序,加入后为“至尊VIP终身塔,验证通过,加密代码如下:
function md5_Utf8Encode(string) {
string = string.replace(/\r\n/g, "\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
};
签名往往有一个参数拼接要求和字母排序,一开始的时候以为参数少,自己拼接一下就完了,但在支付的时候因为请求参数太多,从而改变了我的注意,决定写一个获取一个待签名字符串的方法,如下:
/**
* 根据请求参数(a=1&b=2&c=3...)和key获取要加密的字符串
* @param params
* @param key
* @returns {string}
*/
getSignParams = function (params, key) {
var paramsArr = params.split("&");
paramsArr.sort();
var signStr = "";
for(var i in paramsArr){
var signStrArr = paramsArr[i].split("=");
if(signStrArr[1].length > 0)
{
// 此处自定义签名规则
signStr += signStrArr[0] + md5_Utf8Encode(signStrArr[1]);
}
}
signStr += key;
return signStr;
}
3、uuid
支付过程中有一个参数为uuid,生成代码如下:
/**
* 获取uuid
* @returns {string}
*/
function uuid() {
var s = [];
var hexDigits = "0123456789abcdef";
for (var i = 0; i < 36; i++) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
}
s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
s[8] = s[13] = s[18] = s[23] = "-";
var uuid = s.join("");
return uuid;
}
4、支付页面跳转
软件平台的局限问题,并不能把支付接口完全平台化,获取支付信息后,需要自己把页面展示出来。我是第一次碰到这中情况,起初想通过建立新的页面,我跳转的页面信息,通过getElementById("div").innerHTML = ""的方式展示出来,但结果并没有凑效;也尝试过js动态创建<div>的方式:var ndiv = document.createElement("div");方式创建,效果不理想;最终一句代码搞定:
document.write(json.data.pay_info);
展示出新的页面并没有结束,有个问题在起初并没有考虑到,就是支付完成后的跳转问题,平台提供了跳转参数,但是html5产品貌似只能跳转到入口index.html上,初始化到登录页面,所携带的参数是支付票据,并不是第一次进入游戏时候平台给与的初始化参数(token,openid)等。最终使用cookie保存参数,并解决问题:
if(token == null)
{
access_token = getCookie("token");
}
else
{
access_token = token;
setCookie("token", token);
}
/**
* 保存cookie
* @param name
* @param value
*/
function setCookie(name,value)
{
var Days = 30;
var exp = new Date();
exp.setTime(exp.getTime() + Days*24*60*60*1000);
document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString();
}
/**
* 提取cookie
* @param name
* @returns {null}
*/
function getCookie(name)
{
var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)");
if(arr=document.cookie.match(reg))
return unescape(arr[2]);
else
return null;
}
5、获取请求客户端ip
导入搜狐提供的js后使用
<script src="http://pv.sohu.com/cityjson?ie=utf-8"></script>
获取地址,个人有点担心取得为空,多次一举一下:
var ip = returnCitySN["cip"] == null ? "192.168.0.1" : returnCitySN["cip"];
6、其他注意
1、App平台接html5产品,最大的局限还是在调试上,只能通过alert或者promt输出在手机上,不过可以拿到平台参数后,在浏览器中调试;
2、平台给定的url如果在验证一直通过不了的情况下,换一下地址试试。我在接入中就遇到此问题,测试地址签名验证无法通过,正式地址可以;
3、系统文档在不严谨的情况下,要咨询平台技术,因为有时候标记的所谓“不必要”参数,也在他们的平台中列入了签名算法。
成熟的平台,后两条可忽略;