手机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 相关文章推荐
jQuery JSON的解析方式分享
Apr 05 Javascript
javascript权威指南 学习笔记之变量作用域分享
Sep 28 Javascript
Javascript无阻塞加载具体方式
Jun 28 Javascript
页面图片浮动左右滑动效果的简单实现案例
Feb 10 Javascript
JQuery+CSS实现图片上放置按钮的方法
May 29 Javascript
jQuery 如何给Carousel插件添加新的功能
Apr 18 Javascript
axios基本入门用法教程
Mar 25 Javascript
小程序实现长按保存图片的方法
Dec 31 Javascript
Node.js创建一个Express服务的方法详解
Jan 06 Javascript
JavaScript实现旋转木马轮播图
Mar 16 Javascript
JS sort方法基于数组对象属性值排序
Jul 10 Javascript
wepy--用vantUI 实现上弹列表并选择相应的值操作
Nov 03 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
使用php记录用户通过搜索引擎进网站的关键词
2014/02/13 PHP
php实现URL加密解密的方法
2016/11/17 PHP
符合标准的js表单提交的代码
2007/09/13 Javascript
jQuery chili图片远处放大插件
2009/11/30 Javascript
JavaScript 空位补零实现代码
2010/02/26 Javascript
对frameset、frame、iframe的js操作示例代码
2013/08/16 Javascript
setTimeout和setInterval的深入理解
2013/11/08 Javascript
javascript动态控制服务器控件实例
2014/09/05 Javascript
jQuery获取页面元素绝对与相对位置的方法
2015/06/10 Javascript
JavaScript实现模仿桌面窗口的方法
2015/07/18 Javascript
javascript从作用域链谈闭包
2020/07/29 Javascript
js实现拖拽功能
2017/03/01 Javascript
浅析Vue下的components模板使用及应用
2019/11/27 Javascript
微信小程序批量上传图片到七牛(推荐)
2019/12/19 Javascript
Python脚本实现代码行数统计代码分享
2015/03/10 Python
实现python版本的按任意键继续/退出
2016/09/26 Python
Python实现 多进程导入CSV数据到 MySQL
2017/02/26 Python
python实现最长公共子序列
2018/05/22 Python
python xlsxwriter创建excel图表的方法
2018/06/11 Python
python正则表达式去除两个特殊字符间的内容方法
2018/12/24 Python
Python3.7 新特性之dataclass装饰器
2019/05/27 Python
Python进阶:生成器 懒人版本的迭代器详解
2019/06/29 Python
PyQt5基本控件使用详解:单选按钮、复选框、下拉框
2019/08/05 Python
树莓派4B+opencv4+python 打开摄像头的实现方法
2019/10/18 Python
python程序如何进行保存
2020/07/03 Python
Python爬虫爬取微信朋友圈
2020/08/06 Python
利用Python实现学生信息管理系统的完整实例
2020/12/30 Python
CSS3实现多背景展示效果通过CSS3定位多张背景
2014/08/10 HTML / CSS
香港演唱会订票网站:StubHub香港
2019/10/10 全球购物
Myprotein中国网站:欧洲畅销运动营养品牌
2021/02/11 全球购物
护理专科毕业推荐信
2013/11/10 职场文书
放飞蜻蜓反思
2014/02/05 职场文书
酒店总经理助理职责
2014/02/12 职场文书
《飞向蓝天的恐龙》教学反思
2014/04/09 职场文书
灰雀教学反思
2014/04/28 职场文书
市级青年文明号申报材料
2014/05/26 职场文书