手机Web APP如何实现分享多平台功能


Posted in Javascript onAugust 19, 2016

话说App一般都带有分享到社交平台的入口,web网页的分享也有很不错的框架,但是随着HTML5的不断发展,手机web页面越来越多的进入到我们的生活中,那如何在我们的手机上完成分享呢?话说各大分享平台都有针对Android、Ios的SDK,作为开发者,我们只需要将SDK集成的我们的项目中即可,通过提供的外部接口,我们可以很容易的完成分享的功能;web网页呢,网上也存在很多优秀的分享框架,例如:bShare分享 、JiaThis分享;我们可以很方便的集成到我们的项目中;但是手机web页面实现分享就需要我们下点功夫了,以为这个时候,我们就可以通过调用用户安装的客户端进行分享,这里需要特别提到的就是微信分享了,网页端我们分享时,一般都是弹出一个分享的二维码,我们使用微信App扫描然后进行分享,手机端我们就不能这样操作了,我们需要当用户选中微信分享时,直接打开App进行分享,这里就要吐槽一下微信的分享JS SDK了,初次接触到这个东东时,还以为只要完成操作就可以实现自定义分享了,随着各种坑不断,最后发现,微信JS SDK仅仅只是将我们的自定义内容临时缓存,当我们需要分享时,还是需要通过微信右上角的按钮来完成操作的。好嘞,不多讲废话了,进入今天的主题,接下来我将按照通过超链接完成新浪、QQ、QQ空间、腾讯微博分享,然后为大家奉上基于C#平台的微信JS SDK分享组件的签名逻辑,最后带领大家完成手机web端分享。

进入第一点:通过超链接完成分享

对于常用的社交平台我们基本可以通过超链接的方式进行内容分享,当然微信除外,微信不支持这种分享方式,这种分享方式可以便于我们自定义分享,并且使用起来非常的方便。

function shareSina() {
//分享到新浪微博
var sharesinastring = 'http://service.weibo.com/share/share.php?title=' + $("#title").val() + '&url=' + $("#url").val();
window.location.href = sharesinastring;
}
function shareQQzone(){
var p = {
url:location.href,
showcount:'0',/*是否显示分享总数,显示:'1',不显示:'0' */
desc:'',/*默认分享理由(可选)*/
summary:'',/*分享摘要(可选)*/
title:'',/*分享标题(可选)*/
site:'满艺网',/*分享来源 如:腾讯网(可选)*/
pics:'', /*分享图片的路径(可选)*/
style:'203',
width:98,
height:22
};
//分享到QQ空间
var sharesinastring = 'http://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey?title=' + $("#title").val() + '&url=' + $("#url").val() + '&site="满艺网"';
window.location.href = sharesinastring;
}
function shareQQ() {
var p = {
url: location.href, /*获取URL,可加上来自分享到QQ标识,方便统计*/
desc: '', /*分享理由(风格应模拟用户对话),支持多分享语随机展现(使用|分隔)*/
title: '', /*分享标题(可选)*/
summary: '', /*分享摘要(可选)*/
pics: '', /*分享图片(可选)*/
flash: '', /*视频地址(可选)*/
site: '满艺网', /*分享来源(可选) 如:QQ分享*/
style: '201',
width: 32,
height: 32
};
//分享到QQ
var sharesinastring = 'http://connect.qq.com/widget/shareqq/index.html?title=' + $("#title").val() + '&summary=' + $("#url").val() + '&url=' + $("#url").val() + '&site="满艺网"';
window.location.href = sharesinastring;
}
function shareQQweibo() {
var p = {
url: location.href, /*获取URL,可加上来自分享到QQ标识,方便统计*/
title: '', /*分享标题(可选)*/
pic: '', /*分享图片(可选)*/
site: '满艺网' /*分享来源(可选) 如:QQ分享*/
};
//分享到腾讯微博
var sharesinastring = 'http://v.t.qq.com/share/share.php?title=' + $("#title").val() + '&url=' + $("#url").val() + '&site="满艺网"';
window.location.href = sharesinastring;
}

以上便是分享都新浪微博、QQ、QQ空间、腾讯微博的JS代码,我们只需要在页面需要分享的位置进行一下调用即可。当然还有很多平台,一样支持这种形式的分享内容,各位小伙伴自己去摸索吧,这里我们不再一一赘述。

下面介绍一些微信分享:

一开始我们便说道微信内置的浏览器右上角带有分享功能,这也导致我们在自己的网页上无法直接分享到微信的朋友圈,而微信为我们提供了一个用于微信自定义分享的JS SDK,小伙伴是不是已经按耐不住自己的激情了,下面我们来先简单看一这个JS SDK为何物?微信官方提供的文档到时挺详细,但是想要开发JS SDK我们首先需要一个微信公众号,然后我们点击“接口权限”可以查看到我们所拥有的权限,如下:

手机Web APP如何实现分享多平台功能

对于上面这些基本的东西就不在多说,下面我们重点看一下如何获取jsapi_ticket,如何进行签名。官方文档提示的步骤是,先获取access_token,然后通过access_token来获取jsapi_ticket,最后通过jsapi_ticket进行签名。下面我们就一步一步完成上面的工作。注:官方提供了php、java、python、nodejs的实例程序,这里我将以C#为例为大家结束如何完成上面的操作。

第一步、获取access_token

官方文档是这样说的:access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。

手机Web APP如何实现分享多平台功能

第二步获取jsapi_ticket

官方文档是这样说的:jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket 。

1.参考以下文档获取access_token(有效期7200秒,开发者必须在自己的服务全局缓存access_token):../15/54ce45d8d30b6bf6758f68d2e95bc627.html

手机Web APP如何实现分享多平台功能

2.用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket):https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi

获得jsapi_ticket之后,就可以生成JS-SDK权限验证的签名了。

  第三步生成JS-SDK权限验证的签名

签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。

手机Web APP如何实现分享多平台功能

注意事项

1.签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同;

2.签名用的url必须是调用JS接口页面的完整URL;

3.出于安全考虑,开发者必须在服务器端实现签名的逻辑。

以上便是微信JS SDK的签名逻辑部分,下面奉上具体的代码实现:

using System;
using System.Net;
using System.Web.Mvc;
using System.IO;
using System.Text;
using System.Web.Script.Serialization;
using ManYiAbyWAP.Models;
/// <summary>
/// 微信获取jsapi_ticket
/// </summary>
namespace ManYiAbyWAP.Controllers
{
public class WXMessageController : Controller
{
private static string APPID = "微信提供的appid";
private static string SECRECT = "微信提供的secrect";
public static WXInfo accessToken = null;//全局对象,每7200秒更新一次,微信对每日获取Token有请求次数与时效限制
public static DateTime overTime = DateTime.Now;//用于Token的过期验证
public ActionResult GetToken(string url) {
if (accessToken != null)
{
TimeSpan span = Convert.ToDateTime(overTime).Subtract(Convert.ToDateTime(DateTime.Now));
if (span.TotalHours > 2)
{
accessToken = GETWinXinToken();
overTime = DateTime.Now;
}
}
else
{
accessToken = GETWinXinToken();
overTime = DateTime.Now;
}
//生成签名的时间戳
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
accessToken.timestamp = Convert.ToInt64(ts.TotalSeconds).ToString();
//获取随机串
accessToken.noncestr = createNonceStr(16);
string str = "jsapi_ticket="+ accessToken .ticket+ "&noncestr="+ accessToken.noncestr + "×tamp="+ accessToken.timestamp + "&url="+ url;
accessToken.signature = SHA1(str).ToLower();
accessToken.APPID = APPID;
return Json(accessToken, JsonRequestBehavior.AllowGet);
}
//生成随机串
private string createNonceStr(int length = 16)
{
string str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Random r = new Random();
string result = string.Empty;
//生成一个8位长的随机字符,具体长度可以自己更改
for (int i = 0; i < length; i++)
{
int m = r.Next(0, 62);//这里下界是0,随机数可以取到,上界应该是62,因为随机数取不到上界,也就是最大62,符合我们的题意
string s = str.Substring(m, 1);
result += s;
}
return result;
}
//散列算法
private static string SHA1(string text)
{
byte[] cleanBytes = Encoding.Default.GetBytes(text);
byte[] hashedBytes = System.Security.Cryptography.SHA1.Create().ComputeHash(cleanBytes);
return BitConverter.ToString(hashedBytes).Replace("-", "");
}
//通过GET请求获取Token
private static WXInfo GETWinXinToken() {
//获取access_token
HttpWebResponse response = CreateGetHttpResponse("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + APPID + "&secret=" + SECRECT, 5000);
StreamReader reader = new StreamReader(response.GetResponseStream());
String line;
StringBuilder sb = new StringBuilder();
while ((line = reader.ReadLine()) != null)
{
sb.Append(line.ToString());
}
JavaScriptSerializer js = new JavaScriptSerializer();
WXInfo accessToken = js.Deserialize<WXInfo>(sb.ToString());
//获取jsapi_ticket
response = CreateGetHttpResponse("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + accessToken.access_token + "&type=jsapi", 5000);
reader = new StreamReader(response.GetResponseStream());
sb = new StringBuilder();
while ((line = reader.ReadLine()) != null)
{
sb.Append(line.ToString());
}
accessToken = js.Deserialize<WXInfo>(sb.ToString());
return accessToken;
}
/// <summary> 
/// 创建GET方式的HTTP请求 
/// </summary> 
/// <param name="url">请求的URL</param> 
/// <param name="timeout">请求的超时时间</param> 
/// <param name="userAgent">请求的客户端浏览器信息,可以为空</param> 
/// <param name="cookies">随同HTTP请求发送的Cookie信息,如果不需要身份验证可以为空</param> 
/// <returns></returns> 
public static HttpWebResponse CreateGetHttpResponse(string url, int? timeout, string userAgent=null, CookieCollection cookies=null)
{
if (string.IsNullOrEmpty(url))
{
throw new ArgumentNullException("url");
}
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.Method = "GET";
if (!string.IsNullOrEmpty(userAgent))
{
request.UserAgent = userAgent;
}
if (timeout.HasValue)
{
request.Timeout = timeout.Value;
}
if (cookies != null)
{
request.CookieContainer = new CookieContainer();
request.CookieContainer.Add(cookies);
}
return request.GetResponse() as HttpWebResponse;
}
}
}

用于存放Token信息的全局对象WXInfo.cs

namespace ManYiAbyWAP.Models
{
/// <summary>
/// 微信获取Token返回参数类
/// </summary>
public class WXInfo
{
public string APPID { get; set; }
public string access_token { get; set; }//access_token
public string expires_in { get; set; }//Token过期时间,7200秒内有效
public string ticket { get; set; }//jsapi_ticket
public string errmsg { get; set; }
public int errcode { get; set; }
public string noncestr { get; set; }//生成签名的随机串
public string timestamp { get; set; }//生成签名的时间戳
public string signature { get; set; }//签名返回值
}
}

网页端进行初始化的JS代码:

//微信JS SDK请求状态
var requestStatus = 0;
function shareWX() {
if (requestStatus != 1) {
requestStatus = 1;//正在请求
var ajaxPara = "url=" + encodeURIComponent(window.location.href.split('#')[0]);
$.ajax({
url: '/WXMessage/GetToken',
dataType: 'json',
data: ajaxPara,
success: function (json) {
if (undefined != json && json !== "") {
var jsonObjs = eval(json);
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: jsonObjs.APPID, // 必填,公众号的唯一标识
timestamp: jsonObjs.timestamp, // 必填,生成签名的时间戳
nonceStr: jsonObjs.noncestr, // 必填,生成签名的随机串
signature: jsonObjs.signature,// 必填,签名,见附录1
jsApiList: [
'checkJsApi',
'onMenuShareTimeline',
'onMenuShareAppMessage',
'onMenuShareQQ',
'onMenuShareWeibo',
'onMenuShareQZone'
] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
wx.ready(function () {
//alert("微信验证成功");
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
wx.checkJsApi({
jsApiList: [
'checkJsApi',
'onMenuShareTimeline',
'onMenuShareAppMessage',
'onMenuShareQQ',
'onMenuShareWeibo',
'onMenuShareQZone'
], // 需要检测的JS接口列表,所有JS接口列表见附录2,
success: function (res) {
// 以键值对的形式返回,可用的api值true,不可用为false
// 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"}
}
});
wx.onMenuShareWeibo({
title: '满艺网分享测试', // 分享标题
desc: '满艺网分享描述测试', // 分享描述
link: 'http://www.manyiaby.com', // 分享链接
imgUrl: 'http://www.manyiaby.com/img/logo_2.jpg', // 分享图标
success: function () {
// 用户确认分享后执行的回调函数
alert("分享成功");
},
cancel: function () {
// 用户取消分享后执行的回调函数
alert("分享取消");
}
});
});
wx.error(function (res) {
//alert("微信验证失败 res:"+res);
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
});
requestStatus = 2;//请求完成
}
},
complete: function () {
window.setTimeout(function () {
requestStatus = 2;//请求完成
}, 300);
}
});
}

到这里关于微信分享JS SDK的使用就为大家介绍完毕,大家可以结合自己的需求进行参考。一开始已经为大家介绍了,微信提供的分享JS SDK仅仅只是一个对于微信内部浏览器的缓存处理,真正的分享还是需要我们点击右上角的分享按钮。 

 上面这些都不是太完美的手机web分享解决方法,最后给大家介绍一些Sosh社会化分享组件,当我看到这个组件时,我就知道这是我需要的,简洁的界面,整好可以让我们的网站看起来典雅舒服。好了,废话不多说,进入主题:

手机Web APP如何实现分享多平台功能

以上所述是小编给大家介绍的手机Web APP如何实现分享多平台功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
判断一个变量是数组Array类型的方法
Sep 16 Javascript
JQuery中$.each 和$(selector).each()的区别详解
Mar 13 Javascript
JS+CSS实现类似QQ好友及黑名单效果的树型菜单
Sep 22 Javascript
jQuery的选择器中的通配符[id^='code']或[name^='code']及jquery选择器总结
Dec 24 Javascript
Bootstrap登陆注册页面开发教程
Jul 12 Javascript
js实现前端分页页码管理
Jan 06 Javascript
JS小数转换为整数的方法分析
Jan 07 Javascript
利用Vue.js实现checkbox的全选反选效果
Jan 18 Javascript
基于vue2实现左滑删除功能
Nov 28 Javascript
vue短信验证性能优化如何写入localstorage中
Apr 25 Javascript
为jquery的ajax请求添加超时timeout时间的操作方法
Sep 04 jQuery
详解Vue中的MVVM原理和实现方法
Jul 15 Javascript
浅谈Javascript中的12种DOM节点类型
Aug 19 #Javascript
js实现select选择框效果及美化
Aug 19 #Javascript
JavaScript面向对象编写购物车功能
Aug 19 #Javascript
javascript设计模式之module(模块)模式
Aug 19 #Javascript
JS实现六位字符密码输入器功能
Aug 19 #Javascript
javascript简单实现跟随滚动条漂浮的返回顶部按钮效果
Aug 19 #Javascript
巧用jQuery选择器提高写表单效率的方法
Aug 19 #Javascript
You might like
第八节--访问方式
2006/11/16 PHP
php set_magic_quotes_runtime() 函数过时解决方法
2010/07/08 PHP
使用PHP生成PDF方法详解
2015/01/23 PHP
php递归删除目录与文件的方法
2015/01/30 PHP
PHP简单实现文本计数器的方法
2016/04/28 PHP
PhpStorm terminal无法输入命令的解决方法
2016/10/09 PHP
php 下 html5 XHR2 + FormData + File API 上传文件操作实例分析
2020/02/28 PHP
Jquery 表单取值赋值的一些基本操作
2009/10/11 Javascript
jquery.validate使用攻略 第二部
2010/07/01 Javascript
JavaScript高级程序设计阅读笔记(十六) javascript检测浏览器和操作系统-detect.js
2012/08/14 Javascript
hover的用法及live的用法介绍(鼠标悬停效果)
2013/03/29 Javascript
jQuery实现点击标题输入详细信息
2013/04/16 Javascript
jQuery拖拽插件gridster使用指南
2015/04/21 Javascript
JS自动倒计时30秒后按钮才可用(两种场景)
2015/08/31 Javascript
JavaScript中iframe实现局部刷新的几种方法汇总
2016/01/06 Javascript
dedecms页面如何获取会员状态的实例代码
2016/03/15 Javascript
jQGrid Table操作列中点击【操作】按钮弹出按钮层的实现代码
2016/12/05 Javascript
信息滚动效果的实例讲解
2017/09/18 Javascript
详解Vue 事件修饰符capture 的使用
2017/12/29 Javascript
extjs4图表绘制之折线图实现方法分析
2020/03/06 Javascript
koa2 数据api中间件设计模型的实现方法
2020/07/13 Javascript
Python使用Flask框架同时上传多个文件的方法
2015/03/21 Python
Python读取Excel的方法实例分析
2015/07/11 Python
Python使用itertools模块实现排列组合功能示例
2018/07/02 Python
Python实用技巧之利用元组代替字典并为元组元素命名
2018/07/11 Python
python 多线程中子线程和主线程相互通信方法
2018/11/09 Python
Django-Rest-Framework 权限管理源码浅析(小结)
2018/11/12 Python
boostrap modal 闪现问题的解决方法
2020/09/01 HTML / CSS
加拿大时尚少女服装品牌:Garage
2016/10/10 全球购物
三星加拿大官方网上商店:Samsung CA
2020/12/18 全球购物
枚举和一组预处理的#define有什么不同
2016/09/21 面试题
计算机应用与科学个人的自我评价
2013/11/15 职场文书
教师中国梦演讲稿
2014/04/23 职场文书
工作作风整顿个人剖析材料
2014/10/11 职场文书
实习生辞职信范文
2015/03/02 职场文书
js实现模拟购物商城案例
2021/05/18 Javascript