官方提供的资料:
腾讯移动Web开发平台 : 15年最后一次更新, 可想而知放在如今QQ中调用的准确性!这里面提供了一些QQWebView 相关配置的接口, 也只是一些接口。官网中提供的“通用API”和“手机QQ”页面中使用的全局对象mqq
,引入方式为:,其中就有不少可以配置分享的接口:
window.mqq.invoke("data","setShareInfo", {
share_url: window.OPEN_DATA && window.OPEN_DATA.shareurl,
title: 'H5应用',
desc: 'H5开放平台',
image_url: 'http://i.gtimg.cn/open/app_icon/05/58/35/77/1105583577_100_m.png'
});
// 另外使用meta同样可以达到该接口的作用
// H5应用设置方法 (我觉得该方法是需要配置腾讯白名单才能正常使用的,否则设置无效,请往下阅读)
mqq.ui.setOnShareHandler(function(type){
mqq.ui.shareMessage({
title: '自定义的分享标题',
desc: '自定义的分享描述',
share_type: type,
share_url: window.OPEN_DATA.shareurl,
image_url: 'http://i.gtimg.cn/open/app_icon/05/58/35/77/1105583577_100_m.png',
back: true
},function(result){
//result
});
});
其中对外分享组件接口文档 中说引入 使用全局
setShareInfo
方法定制手机QQ APP内的分享内容:
setShareInfo({
title: '父爱,在你看不到的地方', // 分享标题
summary: '父爱如山,感觉不到只因身在此山中', // 分享内容
pic: 'http://qzonestyle.gtimg.cn/aoi/sola/20150617094556_OvfOpoRKRB.png', // 分享图片
url: 'http://qzs.qzone.qq.com/qzone/qzact/act/2015/father-day-m/index.html', // 分享链接
});
手机QQ打开 QQAPI官方测试Demo,可以大概看看都提供哪些方法,是否有效,也可以看看源码都如何调用,有助理解。
遇到的问题:
手机QQ 环境下,网页的分享可以不用去使用QQAPI去配置分享样式, 按上面所说直接设置标签就行了, 但是对于 Vue 框架的页面来说,就可能存在问题,确切的说是 Vue 框架中使用 # 控制路由,在QQ中分享出来就可能会出现奇怪的问题( 如果使用 history 路由模式应该不会有问题),下面针对使用 # 作为路由方式的H5在QQ中分享中我所遇到的问题及解决方案进行记录。
Q1 : iPhone QQ 分享出去的页面在 iPhoneQQ 无法打开(服务器报错)或页面 404 (Android打开没有问题)
举个
Hash 模式下的URL是这样的 http://localhost/index.html#/home?a=1
,当该连接在QQ里打开并使用QQ提供的分享功能分享出来的时候,分享出来的链接可能就会变成 http://localhost/index.html&appinstall=0#/home?a=1
,QQ会在URL中自动拼接上&appinstall=0 而且在 # 前面,这就会直接导致服务器解析URL错误,页面无法正常打开。
当然,这种问题并不是100%出现的,根据我目前的尝试,满足以下条件会出现该问题:
URL长度大于140 且 iPhoneQQ 环境分享出去 并 在 iPhoneQQ 打开分享页面
我的解决方案:
我在项目入口文件的 index.html
的中第一行加上替换分享默认参数的JS
...
当然, 如果添加的参数导致服务器无法解析, 也根本就不会进入到这里。所以我想到了下面的方法去避免出现服务器无法解析的URL
项目的main.js
中在配置 router
的时候监听在 iPhoneQQ 环境下,当某页面的URL过长时,在index.html
后添加?1=1
这样可以避免被QQ添加&appinstall=0直接导致URL解析错误。最终分享后打开变成index.html?1=1&appinstall=0
,至少可以正常访问。
router.afterEach((to, from) => {
// 加个延迟, 不然 window.location.href 不会变
setTimeout(function () {
if (mqq && mqq.platform == 'iPhoneQQ' && window.location.href.length > 140) {
// iPhoneQQ 上URL长度大于140会, QQ分享默认会插入参数导致url格式错误从而服务端报错, 需改成 xxx/index.html?1-1#/?param=xxx
console.log(location.href.replace('index.html#', 'index.html?1=1#'))
document.location.replace(location.href.replace('index.html#', 'index.html?1=1#'))
}
}, 100);
})
上述方法可解决问题。
Q2:配置分享样式失效。
一般情况可以通过设置标签即可, 也可以通过 JS 去自行修改内容;
// 手动修改
$("meta[itemprop='name']").attr('content', title)
$("meta[itemprop='description']").attr('content', desc)
这种情况分享出去样式为:Android 标题和子标题是 meta 的 name 和 description
, iPhone 标题是 document.title
,子标题是 meta 的 description
。
也可以使用 QQAPI:
// 引入
setShareInfo({
title: params.title, // 分享标题
summary: params.desc, // 分享内容
pic: 'http://imgcache.qq.com/qqshow/ac/v4/global/logo.png', // 分享图片
url: window.location.href, // 分享链接
})
// 或者 引入
window.mqq.invoke('data', 'setShareInfo', {
share_url: window.location.href,
title: params.title,
desc: params.desc,
image_url: 'http://imgcache.qq.com/qqshow/ac/v4/global/logo.png'
})
使用QQAPI一定要注意的地方
QQAPI 提供的所有方法(包括上面的分享配置方法),我在实验后猜测只在域名为 .com 或 .cn
或者在 “腾讯白名单” 下才有效果,否则怎么设置都没有效果。我司域名 测试环境为 .cn 生产环境为 .cc
,测试环境没问题,生产环境不行。所以在使用前务必请知晓这块,如果真遇到设置无效的情况,估计就是这样原因。坑的我一口老血....(至于怎么加入白名单,没有入口,无从知晓,怕是只有内部跟腾讯合作吧~)
在QQAPI分享配置无效的情况下,配置分享样式可以使用上述的 document.title
和 标签去配置了,但是目前发现,AndroidQQ下如果
index.html
中没有
标签,是无法配置分享样式的,请务必加上。此时 AndroidQQ 分享的标题我觉得应该是页面加载完成后的 document.title
,所以之后再设置 document.title
就无效了。
在QQAPI分享配置有效的情况下,上述两个分享配置方法功能是一样的,效果为:Android分享的样式完全有参数控制,但是iPhone上分享出来的样式为 标题是 document.title
,子标题是 meta 的 description
Q3:QQAPI配置分享无效时,AndroidQQ上,分享通过路由跳转的页面,打开看到的却是首页。
在QQAPI配置分享无效的情况下,我发现仅在AndroidQQ上会出现该问题,明明分享的是其他页面,可打开分享消息展示的却是第一个页面。也就是 Vue的 # 路由机制无法触发QQ去更新分享出去的URL。即使不使用 $router
调整页面,使用 location.href = xxxx
也是不行的。我猜测,只改变 # 后面的路由和参数无法触发 QQ 更新 分享出去的 URL。
我想到使用QQAPI的
mqq.invoke('ui', 'openUrl', {
url: url,
target: 1,
style: 0
})
方法重新打开一个 WebView 展示其他页面,可最终发现在测试环境下可以解决,但生产环境不行,原因就是 .cc
域名下 QQAPI 的方法无效。如果域名后缀是.com 或 .cn
可以尝试用此方法解决子页面分享问题。
最终 我发现在index.html
后面添加参数(index.html?1=1/#hello?a=1
)是可以触发 QQ 更新分享出去的URL的。简直了~
我的解决方案:
if (mqq && mqq.platform.indexOf('AndroidQQ') != -1) {
// AndroidQQ 在域名为.cc下分享无法配置,QQ分享配置监听不了Vue路由变化,即 #后面的变化并不会让 QQWebview 改变分享配置,所以Android这样处理 index.html?1=1 可刷新分享配置
let url = window.location.href.split('index.html')[0] + 'index.html?1=1#/hello?a=1'
window.location.href = url
} else {
this.$router.push({
path: '/hello',
query: {
a: 1
}
})
}
自此,目前关于 Vue 框架写的H5页面在QQ分享的问题基本解决。确实挺坑的,尤其是域名问题。以上是我个人在实践中的整理。如果有什么不对的地方或者有更好的解决方法也请指出和交流。
请注意:iPhoneQQ分享有次数限制,大约100次左右,超出后对方看不到消息,但自己能看到,大约被“封”两天
参考资料
掘金 Crazy_Urus 移动端H5多平台分享实践
Github AOTU Labs 手Q分享接口 - 基础篇
Github AOTU Labs 手Q分享接口 - 填坑篇
CSDN 武东10号 iOS下,H5地址从webview分享到QQ,微信打不开自动拼接appinstall=0地址,问题解决方法