zoukankan      html  css  js  c++  java
  • 一篇搞定微信分享和line分享

    前言

    在h5的页面开发中,分享是不可或缺的一部分,对于一些传播性比较强的页面,活动页之类的,分享功能极为重要。例如,京东等电商年末时会有一系列的总结h5在微信中传播,就不得不提到微信的分享机制。

    微信分享

    最简单的配置

    微信分享静态页
    微信分享需要后台回传时间戳、签名等信息,如果页面比较简单,就可以用下述方法做简单设置。
    微信默认抓取第一张符合要求的图片作为分享图,图片大于300px × 300px,图片不能是display:none的。
    根据上述规则,img的设置可以为这样:

    <img src="//img30.360buyimg.com/mobilecms/jfs/t4033/80/1876911537/17072/11729313/589bec20Nc5555ece.jpg" style="position:absolute;100%;z-index:0;">
    

    要记得把这张图片放到最前面,如果网页加载了其他符合规则的图片,也能保证正常分享。
    (之前看到过一个weixinjsbridge的源码,抓取的规则大概是这样,具体忘记了,后面也找不到那个源代码了,如果有错误,请通知我。)
    分享标题是取页面标题,可以使用js动态修改标题,但是iOS下会有问题,有关修改title的hack,方法如下。

    /**
     * 处理微信设置title问题
     * 页面在加载完成后设置title在微信下不会触发改变
     */
    define(function(){
      return function(src){
        var frame = document.createElement('iframe'),flag = false;
        frame.style.display = 'none';
        frame.onload=frame.onerror=frame.onreadystatechange=function(){
          if(flag){return}
          flag = true;
          setTimeout(function(){document.body.removeChild(frame)},0)
        };
        //
        frame.src = src? (src + (src.indexOf('?') != -1?'&':'?') + '__=' + Date.now()) : '/favicon.ico',
        document.body.appendChild(frame);
      }
    });
    

    类似的hack有很多,基于jquery、原生的也有很多,基本原理就是使用iframe。

    之后分享以后,在朋友圈是这样
    朋友圈分享图
    与好友分享后是这样
    好友分享
    如果对于分享的要求不高,上面的方法就可以了。
    But,怎么可能?

    真正的分享

    在传播性极强的h5活动页中,经常会需要带有不同的图片、定制的描述、title等等,此时,必须要申请一个公众号,并且需要后台的配合,才能完整的使用微信的分享功能。
    申请公众号交给产品,开发接口交给网关,前端要做什么呢?
    先放个官方文档链接,我来简述步骤,如果有疑问,可以留言,或者查阅官方文档。

    1. 页面导入官方js,http://res.wx.qq.com/open/js/jweixin-1.2.0.js。(需要吐槽的是,之前官网是是1.0.0版本,突然变成了1.2.0,毫无通知。。)
    2. 请求接口,获取时间戳、签名等一系列公众号的信息。
    3. 调用wx.config(),把这些必填的信息填入。
    4. 调用wx.ready() 处理一些初始化的内容。此处配置分享到朋友圈、分享给好友的内容。
    5. 调用wx.error()处理错误信息,有时候签名会失效,此处可以重新请求接口,重新进行2-4步。
    6. end
      简单吧,官方文档十分详细,接下来分享一个方法,大家可以自行参考修改。
    var wxShares = function(title, desc, link, imgUrl) {
            // req为我封装的一个ajax方法
            req({
                url: '//youdomainulr.com', // 请求接口url
                success: function(data) {
                    if (typeof data == "string") {
                        data = JSON.parse(data);
                    }
                    // 具体的数据结构不一定是这样,只是例子
                    var appId = data.shareResult.appId,
                        timestamp = data.shareResult.timestamp,
                        nonceStr = data.shareResult.nonceStr,
                        signature = data.shareResult.signature;
                    wx.config({
                        debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                        appId: appId, // 必填,公众号的唯一标识
                        timestamp: timestamp, // 必填,生成签名的时间戳
                        nonceStr: nonceStr, // 必填,生成签名的随机串
                        signature: signature, // 必填,签名,见附录1
                        jsApiList: ['checkJsApi',
                                'openLocation',
                                'getLocation',
                                'onMenuShareTimeline',
                                'onMenuShareAppMessage'
                            ] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
                    });
                    wx.ready(function() {
                        wx.checkJsApi({
                            jsApiList: [
                                'getLocation',
                                'onMenuShareTimeline',
                                'onMenuShareAppMessage'
                            ],
                            success: function(res) {
                                // alert(JSON.stringify(res));
                            }
                        });
                        wx.onMenuShareAppMessage({
                            title: title, // 分享标题
                            desc: desc, // 分享描述
                            link: link, // 分享链接
                            imgUrl: imgUrl, // 分享图标
                            type: 'link', // 分享类型,music、video或link,不填默认为link
                            dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
                            success: function() {
                                console.log("分享成功");
                                    // 用户确认分享后执行的回调函数
                            },
                            cancel: function() {
                                // 用户取消分享后执行的回调函数
                            }
                        });
                        wx.onMenuShareTimeline({
                            title: title, // 分享标题
                            link: link, // 分享链接
                            imgUrl: imgUrl, // 分享图标
                            success: function () {
                                // 用户确认分享后执行的回调函数
                            },
                            cancel: function () {
                                // 用户取消分享后执行的回调函数
                            }
                        });
                    });
    
                }
            });
        };
    

    上面的代码给出了分享到朋友圈和分享给好友的例子,其他还有很多渠道如qq、微博,大同小异,请自行参考官方文档。

    line分享

    微信还不够,我们要做海外站了怎么办?这时需要分享到line。(facebook由于业务不适合,不需要做,我暂时没有研究,如果有空,我会补一篇。)
    老样子,先上官方文档。line被墙了,可能需要翻墙。
    官方文档极为贴心,基本上可以满足大部分需求,我这里也不赘述了,按照官方文档一步步操作很简单。
    But,官网的例子只支持那几种按钮样式,我要自定义样式怎么办?官方提供了提交途径,问题我写一个页面,要搞这么麻烦吗?
    于是我想到了唤起app协议,就这么一搜,哈哈哈哈哈
    google line
    看看贴心的Google智能提示第一个是什么,哈哈哈哈哈哈
    然而,我发现,并不能打开官网,剩下的英文网站也没有解答,日语看不懂。o(╥﹏╥)o ,后来终于找到了一篇博客

    <meta property="og:title" content="標題"/>
    <meta property="og:description" content="內容敘述"/>
    <meta property="og:url" content="分享網址"/>
    <meta property="og:image" content="分享圖片"/>
    

    注意这上面提到的抓取meta,如果非要适配line,可以这么写,如果不需要,就按照正常的配置就行了。

    <title>京东(JD.COM)-正品低价、品质保障、配送及时、轻松购物!</title>
    <meta name="description" content="京东JD.COM-专业的综合网上购物商城,销售家电、数码通讯、电脑、家居百货、服装服饰、母婴、图书、食品等数万个品牌优质商品.便捷、诚信的服务,为您提供愉悦的网上购物体验!">
    <link rel="apple-touch-icon-precomposed" href="//st.360buyimg.com/m/images/apple-touch-icon.png?v=jd201709071824">
    

    line中展示
    如图所示,line内置的爬虫会自己抓取页面上的配置。

    上面的写法基本上就满足我们的需要了。因为line是自行抓取分享过来的链接上的内容,他提到的配置我也懒得上线了,就抄着主站上的内容改一改就行了。哈哈

    接下來我們來看主要的分享連結,這兩個方法就是這次的主角
    //桌機
    "https://lineit.line.me/share/ui?url="+ encodeURIComponent("分享的網址")

    //手機
    "line://msg/text/"+ encodeURIComponent("分享的網址")

    这里需要判断环境,pc的话,就另起标签页,它自己会判断cookie登录与否,否则就用类似openapp的这种协议,去唤起line(如果安装了的话,就会打开line)。
    这里有一个问题,正常来说,如果用户安装了,则自己打开line正常分享,没装的话,就没法打开这种协议了。
    而且,经过我在微信、uc等环境下打开,(我装了line),并不会跳转到line里面,毫无反应,也不提示找不到app。不知道国外的app是不是也是这个调性。
    最后与产品协调解决方案是,判断是否在line中,如果在,调用line分享,否则,弹窗展示一个url,让用户去复制粘贴。o(╥﹏╥)o,也算是降级方案了吧。
    line环境下的webview发送请求时,ua会带有 Line 这个字段,按照这样处理即可。
    方法如下:

    function getPlatform () {
    	var
    		_ua = navigator.userAgent
    		, _iswx = _ua.indexOf('MicroMessenger') != -1
    		, _isLine = _ua.indexOf('Line') != -1
    	;
    	if (_iswx) {
    		return "wx";
    	} else if (_isLine) {
    		return "line";
    	} else {
    		return "m";
    	}
    }
    /**
     ** obj 为share对象,封装需要传递的描述信息
     ** callback 为callback对象,封装了一些不同平台下的回调函数
    */
    function share(obj, callback) {
    	getShareInformation(function () {
    		var
    			shareObj = obj || {}
    			, title = obj.title || '默认title'
    			, desc = obj.desc || '默认描述'
    			, url = obj.url || '默认url'
    			, img = obj.img || '默认图片'
    			, currentPlatform = getPlatform()
    		;
    		switch (currentPlatform) {
    			case 'wx':
    				// TODO 需要请求微信的一些信息
    				callback.wxCallback(shareObj);
    				break;
    			case 'line':
    				window.open('line://msg/text/'+ encodeURIComponent(url),"_blank")
    				break;
    			case 'm':
    				callback.mCallback(shareObj);
    				break;
    			default:
    				callback.mCallback(shareObj);
    				break;
    		}
    	})
    
    }
    

    以上。

  • 相关阅读:
    [LintCode] Valid Palindrome 验证回文字符串
    [LeetCode] 378. Kth Smallest Element in a Sorted Matrix 有序矩阵中第K小的元素
    [LintCode] Integer to Roman 整数转化成罗马数字
    [LintCode] Roman to Integer 罗马数字转化成整数
    [LintCode] Scramble String 爬行字符串
    [LintCode] Count and Say 计数和读法
    [LintCode] Simplify Path 简化路径
    [LintCode] Length of Last Word 求末尾单词的长度
    [LintCode] Valid Parentheses 验证括号
    [LeetCode] 377. Combination Sum IV 组合之和之四
  • 原文地址:https://www.cnblogs.com/liuyongjia/p/7581813.html
Copyright © 2011-2022 走看看