Vue-CLI 的 H5 在手机QQ分享配置的天坑!

官方提供的资料:

腾讯移动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地址,问题解决方法

你可能感兴趣的:(Vue-CLI 的 H5 在手机QQ分享配置的天坑!)