a. 首先, 微信小程序必须是企业认证的, 否则连webview都无法使用.(这个是基础)
b. webview引用页面的JS加入如下脚本(请自行修改去掉不要的内容)
function InitJSSDK(){
// 显示等待
StartWait();
// 发送请求获取json格式的签名信息
var dt = {};
dt.action = "wx_getjsapiticket";
dt.u = window.location.href; // 如果你的URL中有#, 则只要#之前的部分
$.ajax({
url : C_AJAX_HANDLER_URL,
data : dt,
})
.done(function(msg) {
try{
msg = jQuery.parseJSON(msg);
var iCnt = msg.WXJSAPI.length;
if (iCnt > 0){
var obj = msg.WXJSAPI[0];
wx.config({
debug: false,
appId: obj.appid, // 必填,小程序的唯一标识
timestamp: obj.timestamp, // 必填,生成签名的时间戳
nonceStr: obj.nonceStr, // 必填,生成签名的随机串
signature: obj.signature, // 必填,签名
jsApiList: ['getLocation'] // 必填,需要使用的JS接口列表
});
// 调用成功
wx.ready(function(){
bJSSDKOK = true;
setInterval('UpdateLocation()', C_GET_LOCATION_INTERVAL);
})
// 调用失败
wx.error(function(res){
promptError('JSSDK失败: ' + res.errMsg);
bJSSDKOK = false;
});
}
}
catch(e){}
FinishWait();
})
.fail(function() {
promptError('获取JSSDK参数失败!');
FinishWait();
});
}
c. 服务器响应请求的部分:
(代码概要: 实现了获取签名信息, 并存入数据库; 再次申请时会判断是否已经申请过了, 如果已经申请并且没有过期, 则使用现有的,否则重新申请)
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using YQDHWebsite.DB;
/// <summary>
/// WXHelpler - by ssxbxk
/// </summary>
public class WXHelpler
{
private static readonly string GetTokenUrl = ConfigurationManager.AppSettings["GetTokenUrl"];
private static readonly string GetTicketUrl = ConfigurationManager.AppSettings["GetTicketUrl"];
private static readonly string AppID = ConfigurationManager.AppSettings["AppID"];
private static readonly string AppSecret = ConfigurationManager.AppSettings["AppSecret"];
public WXHelpler()
{}
public static string GetJsapiTicket(string szURL) {
string szRet = "";
DataTable dt = GetRecord(szURL);
if (dt.Rows.Count <= 0) {
// 重新申请token, 并记录到数据库中
if (RequestTokenAndTicket(szURL))
dt = GetRecord(szURL);
}
szRet = Tools.DataTableToJson("WXJSAPI", dt);
return szRet;
}
/// <summary>
/// 查询现有的记录
/// </summary>
/// <returns>现有记录</returns>
private static DataTable GetRecord(string szURL) {
string szSQL = @"SELECT * FROM [dbo].[T_WXJSAPI]
WHERE appid=@appid AND secret=@secret AND pageurl=@pageurl";
SqlParameter[] sqlParams = new SqlParameter[]
{
new SqlParameter("@appid", AppID),
new SqlParameter("@secret", AppSecret),
new SqlParameter("@pageurl", szURL)
};
// 如果过期了, 则删除旧数据
DataTable dt = SQLServerHelper.ExecuteDtTxt(szSQL, sqlParams);
if (dt.Rows.Count > 0 && (DateTime)dt.Rows[0]["expires_time"] < DateTime.Now)
{
string szSQLDelete = @"DELETE FROM [dbo].[T_WXJSAPI] WHERE appid=@appid AND secret=@secret AND pageurl=@pageurl";
SQLServerHelper.ExecuteNonQuery(szSQLDelete, sqlParams);
dt = SQLServerHelper.ExecuteDtTxt(szSQL, sqlParams);
}
return dt;
}
/// <summary>
/// 请求服务器, 重新获取Token和ticket并写入数据库
/// </summary>
private static bool RequestTokenAndTicket(string szURL) {
bool bRet = false;
try {
// 获取Access Tocken
string szRQ = GetTokenUrl.Replace("{appid}", AppID).Replace("{secret}", AppSecret);
string szResp = Utils.HttpGet(szRQ);
if (szResp.Length > 0)
{
WXAccessToken accessToken = new WXAccessToken();
accessToken = (WXAccessToken)JsonHelper.JsonToObject(szResp, accessToken);
if (accessToken.access_token.Length > 0) {
// 获取Ticket
szRQ = GetTicketUrl.Replace("{access_token}", accessToken.access_token);
szResp = Utils.HttpGet(szRQ);
if (szResp.Length > 0) {
WXTicket ticket = new WXTicket();
ticket = (WXTicket)JsonHelper.JsonToObject(szResp, ticket);
if (ticket.errcode == "0") {
// 生成随机字符串, 时间戳, 然后通过SHA1方法生成签名
string szNonceStr = Guid.NewGuid().ToString();
DateTime dtNow = DateTime.Now;
string szTimeStamp = Utils.GetTimeStamp(dtNow);
// 将数据记录到数据库中
long lTS = long.Parse(szTimeStamp) + (long.Parse(ticket.expires_in)*1000);
DateTime dtExpiresTime = Utils.ConvertStringToDateTime(lTS.ToString());
szTimeStamp = szTimeStamp.Substring(0, 10);
string szTmp = String.Format(@"jsapi_ticket={0}&noncestr={1}×tamp={2}&url={3}",
ticket.ticket, szNonceStr, szTimeStamp, szURL);
string szSignature = Utils.SHA1(szTmp).ToLower();
string szSQL = @"INSERT INTO [dbo].[T_WXJSAPI]([appid],[secret],[pageurl],[access_token],[ticket],
[nonceStr],[timestamp],[signature],[expires_time])
VALUES (@appid, @secret, @pageurl, @access_token, @ticket, @nonceStr,@timestamp,@signature,@expires_time)";
SqlParameter[] sqlParams = new SqlParameter[]
{
new SqlParameter("@appid", AppID),
new SqlParameter("@secret", AppSecret),
new SqlParameter("@pageurl", szURL),
new SqlParameter("@access_token", accessToken.access_token),
new SqlParameter("@ticket", ticket.ticket),
new SqlParameter("@nonceStr", szNonceStr),
new SqlParameter("@timestamp", szTimeStamp),
new SqlParameter("@signature", szSignature),
new SqlParameter("@expires_time", dtExpiresTime)
};
bRet = SQLServerHelper.ExecuteNonQuery(szSQL, sqlParams) == 1;
}
}
}
}
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
}
return bRet;
}
}
d. web.config中相应的配置
<appSettings>
<!-- 公众号/订阅号的AppID -->
<add key="AppID" value="wxXXXXXXXXXXXXXXXXXX" />
<!-- 公众号/订阅号的AppSecret -->
<add key="AppSecret" value="XXXXXXXXXXXXXXXXXXXXXXXX" />
<!-- 获取Token的URL -->
<add key="GetTokenUrl" value="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={appid}&secret={secret}" />
<!-- 获取Ticket的URL -->
<add key="GetTicketUrl" value="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={access_token}&type=jsapi" />
<!-- 数据库配置 -->
<add key="BaseCon" value="server=XXXXXXXXXXX;database=XXXX;user=XXXX;password=XXXXX;"/>
</appSettings>
e. 数据库表结构
/*
Navicat SQL Server Data Transfer
Source Server : 73
Source Server Version : 110000
Source Host : localhost:1433
Source Database : yqdh
Source Schema : dbo
Target Server Type : SQL Server
Target Server Version : 110000
File Encoding : 65001
Date: 2018-08-07 11:50:29
*/
-- ----------------------------
-- Table structure for T_WXJSAPI
-- ----------------------------
DROP TABLE [dbo].[T_WXJSAPI]
GO
CREATE TABLE [dbo].[T_WXJSAPI] (
[appid] nvarchar(50) NOT NULL ,
[secret] nvarchar(50) NOT NULL ,
[pageurl] nvarchar(200) NOT NULL ,
[access_token] nvarchar(1024) NOT NULL ,
[ticket] nvarchar(1024) NOT NULL ,
[nonceStr] nvarchar(50) NOT NULL ,
[timestamp] nvarchar(50) NOT NULL ,
[signature] nvarchar(50) NOT NULL ,
[expires_time] datetime NOT NULL
)
GO
-- ----------------------------
-- Indexes structure for table T_WXJSAPI
-- ----------------------------
-- ----------------------------
-- Primary Key structure for table T_WXJSAPI
-- ----------------------------
ALTER TABLE [dbo].[T_WXJSAPI] ADD PRIMARY KEY ([appid], [secret], [pageurl])
GO