昨天开始搞分享到微信朋友圈,要求直接调用微信APP的分享到朋友圈。。。
1:首先你需要完成微信的六大前期准备工作,这也是最烦人的。请仔细阅读微信的APP文档:
文档地址:https://mp.weixin.qq.com/wiki/11/74ad127cc054f6b80759c40f77ec03db.html
1.1 绑定域名 这种东西,需要注册,需要实名制,还不能注册为个人模式,要不不给接口使用权限,请注意...
最终的要是你需要 有域名,还有获取 微信给你的2个 值 ,AppId 和 AppSecret
1.2, 这个简单,看文档就好
1.3:这个按照他的方式 ,我实现的代码如下:缓存什么的我就没写了,因为只是Demo,jsapi_ticket每天只能获取2000次,如果你只是研发应该够用
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace HuaSharp.SunCms.WebSite.RongYM
{
public partial class wxTest : System.Web.UI.Page
{
//公众号ID,为了获取还需要拿自己的微信去注册,各种验证实名制,尼玛真麻烦
public static string AppId = "wxea8cd26d4b77ebd9";
//公众号的密钥 ,注册后各种操作登录后获得.
public static string AppSecret = "01187a13372d431a398458ec49b77a10";
//全局缓存对象 有效时间 2小时 微信JS接口的临时票据
public static string jsapi_ticket = "";
//用它来获取 jsapi_ticket ,它的有效期也是2小时,开发者必须在自己的服务全局缓存access_token , 它的值是通过接口获得的.
//access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token
//access_token的有效时间可能会在未来有调整,所以中控服务器不仅需要内部定时主动刷新,还需要提供被动刷新access_token的接口,这样便于业务服务器在API调用获知access_token已超时的情况下,可以触发access_token的刷新流程
public static string access_token = "";
//傻逼微信还需要传入时间撮来完成它的机密算法
public static string timestamp = "";
//傻逼微信还需要传入当前页面的url来完成它的加密算法
public static string curUrl = "";
//尼玛,还需要一个随机串,来给它完成加密验证,恶心死了
public static string noncestr = "zyq";
//上面那么多垃圾东西,那么多次访问httpget,那么多次缓存,就是为了这个垃圾签名.
public static string signature = "";
protected void Page_Load(object sender, EventArgs e)
{
// access_token = "nC_O_2yUvP0CEcstb2wfTpP-zEOfJEyggcEWvrwAO1sO8H1TRpgjCJBmOPqCepcUOz64r0SKI8UTSSgY5Y8tmicCMZ3MKaATYVwppHXOiwmWOTImxDkIUMx1GEoO3MkaGDZfAEAURN";
if (string.IsNullOrWhiteSpace(access_token))
{ //获取access_token
string url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + AppId + "&secret=" + AppSecret;
string result = GetHttp(url, this.Context);
wxApiModel xwapi = JsonToObj(result, typeof(wxApiModel)) as wxApiModel;
access_token = xwapi.access_token;
//{ "access_token":"RlUQfwT7ALMEhpd7d-lwwdVl1L-shnlpR0f52dZdGTgETMXDik6kSlbsn0YywWDyt2DhcUo7bprg6lpfuCrdF3tDFlUrpj8Gt17jnuTxNBmW0HzTa7HWxYqLzX7AayvVPFSgAIADTG","expires_in":7200}
}
// jsapi_ticket = "kgt8ON7yVITDhtdwci0qeRexnVHaoFgZBri5CQ_FeuE26sRqPoRdqWba5z2zCcjWdvw70MKC3YJAvK9ieHSo7w";
//用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket
if (string.IsNullOrWhiteSpace(jsapi_ticket))
{
string url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + access_token + "&type=jsapi";
string result = GetHttp(url, this.Context);
wxApiModel xwapi = JsonToObj(result, typeof(wxApiModel)) as wxApiModel;
jsapi_ticket = xwapi.ticket;
//{
// "errcode": 0,
// "errmsg": "ok",
// "ticket": "kgt8ON7yVITDhtdwci0qeRexnVHaoFgZBri5CQ_FeuHhRjNuvsKJ2ewt9V8iAZa2aorvGWgaPOgJkmRG442DZg",
// "expires_in": 7200
//}
}
timestamp = GenerateTimeStamp();
curUrl = this.Request.Url.ToString();
//string param = "jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW×tamp=1414587457&url=http://mp.weixin.qq.com?params=value";
string param = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + noncestr + "×tamp=" + timestamp + "&url=" + curUrl;
//通过SHA1加密算法获得签名
signature = FormsAuthentication.HashPasswordForStoringInConfigFile(param, "SHA1");
}
public static string GetHttp(string url, HttpContext httpContext)
{
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "GET";
httpWebRequest.Timeout = 20000;
HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
StreamReader streamReader = new StreamReader(httpWebResponse.GetResponseStream());
string responseContent = streamReader.ReadToEnd();
httpWebResponse.Close();
streamReader.Close();
return responseContent;
}
/// <summary>
/// 获取时间撮
/// </summary>
/// <returns></returns>
public static string GenerateTimeStamp()
{
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalSeconds).ToString();
}
/// <summary>
/// 把JSON 格式 转换成List<Model>
/// </summary>
/// <param name="json"></param>
/// <param name="t"></param>
/// <returns></returns>
public static Object JsonToObj(String json, Type t)
{
try
{
System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(t);
using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
return serializer.ReadObject(ms);
}
}
catch
{
return null;
}
}
}
public class wxApiModel
{
public string access_token { get; set; }
public string expires_in { get; set; }
public string errcode { get; set; }
public string errmsg { get; set; }
public string ticket { get; set; }
}
}
然后前台代码如下:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="wxTest.aspx.cs" Inherits="HuaSharp.SunCms.WebSite.RongYM.wxTest" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script type="text/javascript">
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '<%=AppId%>', // 必填,公众号的唯一标识
timestamp: <%=timestamp%>, // 必填,生成签名的时间戳
nonceStr: '<%=noncestr%>', // 必填,生成签名的随机串
signature: '<%=signature%>',// 必填,签名,见附录1
jsApiList: ['onMenuShareTimeline'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 onMenuShareTimeline =微信分享到朋友圈,APi地址:
});
window.onload=function(){
alert("当前域名是:<%=curUrl%>");
}
wx.ready(function(){
alert("微信接口初始化完成");
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
});
wx.error(function(res){
alert("微信接口初始化失败;错误信息:"+res);
// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
});
function Demo()
{
//alert("123");
wx.checkJsApi({
jsApiList: ['onMenuShareTimeline'], // 需要检测的JS接口列表,所有JS接口列表见附录2,
success: function(res) {
alert(res);
debugger;
// 以键值对的形式返回,可用的api值true,不可用为false
// 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"}
}
});
}
function Demo2()
{
wx.onMenuShareTimeline({
debug: true,
title: '微信测试分享', // 分享标题
link: 'http://rym.huasharp.com/RongYM/wxTest.aspx', // 分享链接
imgUrl: 'http://rym.huasharp.com/UploadFiles/20170414111448.jpg', // 分享图标
success: function () {
// 用户确认分享后执行的回调函数
alert("分享成功");
},
cancel: function () {
// 用户取消分享后执行的回调函数
alert("分享失败");
},
complete:function()
{
alert("complete:接口调用完成时执行的回调函数,无论成功或失败都会执行。");
}
});
//alert('已注册获取“分享到朋友圈”状态事件');
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<input type="button" style=" width;200px;height:200px " value="微信测试" onclick="Demo()"/>
<input type="button" style=" width;200px;height:200px " value="微信朋友圈测试" onclick="Demo2()"/>
</div>
<input type="button" style=" width;200px;height:200px " class="btn btn_primary" id="onMenuShareTimeline" value="onMenuShareTimeline"></input>
</form>
</body>
</html>
然后 就可以运行了,在这里我要告诉大家千万要注意的地方
1:有一个比较好的测试工具,在你登录微信公众平台以后,在左边导航有个开发者工具,记得去使用
2:接口权限:正式环境的话,这些接口权限是需要开通的.当然是企业类型的账号,开通以后的样子是这样的:
3:看到第2点是不是怕了?没关系,如果你是开发者的话,在开发工具中有一个测试账号,它拥有大部分权限:
4:测试账号需要注意的地方(你需要有域名,并且在有域名的机器上调试最后一部分,怕了吧?微信的要求就是这么严格,还有注意事项请看图片)
5:请使用微信模拟开发工具,如果你不怕麻烦,用手机直接测试也是可以的.不过功能没这个强大,下载地址在开发者工具里面,具体可以参考这个百度经验:
http://jingyan.baidu.com/article/77b8dc7f9d341f6174eab6ee.html
6:微信接口调用成功以后会有errMess提示,千万被err这几个字给迷惑住,其实是成功了,还有可能会保域名无效错误,这个你需要检查你的域名。
7: 微信分享朋友圈执行了以后,并不是直接调用打开微信app,而是还是需要手动点击右上角的分享.感觉功能真的是弱爆了,搞了这么久。建议大家初始化以后,用户点击分享按钮以后,你提示他使用右上角,初始化分享朋友圈和不分享的区别可以见下图:
这个是没有初始化设置朋友圈分享的页面
8:到这里就结束了,分享成功以后,会有回调方法,我发现我的iphone7 不支持。但是安卓机是支持的....无语了,最后希望微信越做越好。功能越来越强大,不像现在这么麻烦。。。还有这里用的是微信内置浏览器,微信内置浏览器就是说在微信中点击链接,打开的浏览器...好弱... 因为苹果的不开源,苹果上很多浏览器都不支持...UC浏览器还算支持分享到朋友圈的.
有问题可以加我QQ 10200454 询问,我也被这个坑了一天...