虽然微信公众平台的文档已经很详细了,网上相关的资料也很多但是在网上很难搜到免费的完整代码。我初次在网页端使用微信扫一扫时,就遇到了很多问题,现分享出我的完整代码。
步骤一:绑定域名
先登录进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
备注:登录后可在“开发者中心”查看对应的接口权限。
这里注意域名不要带http:// 等前缀。(顺便推荐做微信开发测试时,使用花生壳账号,映射出公网ip。)比如网址: 那么它的域名就是 test.wicp.net。
如果Js安全域名配置错误,扫一扫时会报错:config:invalid url domain
步骤二:引入JS文件
在需要调用JS接口的页面引入如下JS文件,(支持https):
请注意,如果你的页面启用了https,务必引入 ,否则将无法在iOS9.0以上系统中成功使用JSSDK
如需使用摇一摇周边功能,请引入 jweixin-1.1.0.js
备注:支持使用 AMD/CMD 标准模块加载方法加载
这个就是jsp页面直接引入即可
步骤三:通过config接口注入权限验证配置
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,公众号的唯一标识
timestamp: , // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '',// 必填,签名,见附录1
jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
直接贴出前端的代码:
1、weixin.html
-
<!DOCTYPE html>
-
<html>
-
-
<head>
-
<meta charset="UTF-8">
-
<title>Insert title here</title>
-
-
<script type="text/javascript" src="js/jquery-1.11.3.min.js"></script>
-
<script type="text/javascript" src="js/jquery.mobile-1.4.5.min.js"></script>
-
<script src=""></script>
-
<script type="text/javascript" src="js/weixin.js"></script>
-
-
</head>
-
-
<body>
-
<button id="scanQRCode">扫描二维码</button>
-
</body>
-
-
</html>
2、weixin.js
-
//调用微信扫一扫功能所在的页面
-
var url = window.location.href;
-
-
//服务端提供的接口。HOST是服务器的地址,在项目中定义为全局变量;
-
var url11 = HOST + "/tiaoma.do";
-
-
//ajax注入权限验证
-
$.ajax({
-
//与服务器交互
-
url:url11,
-
dataType: 'json',
-
data: {"url" : url},
-
complete: function(XMLHttpRequest, textStatus){
-
-
},
-
error: function(XMLHttpRequest, textStatus, errorThrown){
-
alert("发生错误:"+errorThrown);
-
},
-
success: function(res){
-
var appId = res.appId;
-
var noncestr = res.noncestr;
-
var jsapi_ticket = res.jsapi_ticket;
-
var timestamp = res.timestamp;
-
var signature = res.signature;
-
-
wx.config({
-
debug: true, //开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
-
appId: appId, //必填,公众号的唯一标识
-
timestamp: timestamp, // 必填,生成签名的时间戳
-
nonceStr: noncestr, //必填,生成签名的随机串
-
signature: signature,// 必填,签名,见附录1
-
jsApiList: ['checkJsApi', 'scanQRCode'] //必填,需要使用的JS接口列表,所有JS接口列表 见附录2
-
});
-
}
-
});
-
-
wx.error(function(res) {
-
alert("出错了:" + res.errMsg);
-
});
-
-
//通过ready接口处理成功验证
-
wx.ready(function() {
-
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,
-
//config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,
-
//则须把相关接口放在ready函数中调用来确保正确执行。
-
//对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
-
-
wx.checkJsApi({
-
jsApiList: ['scanQRCode'],
-
success: function(res) {
-
alert(JSON.stringify(res));
-
}
-
});
-
-
//扫描二维码
-
document.querySelector('#scanQRCode').onclick = function() {
-
wx.scanQRCode({
-
needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
-
scanType: ["qrCode", "barCode"], // 可以指定扫二维码还是一维码,默认二者都有
-
success: function(res) {
-
var result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果
-
//document.getElementById("wm_id").value = result; //将扫描的结果赋予到jsp对应值上
-
alert("扫描成功::扫描码=" + result);
-
}
-
});
-
}; //end_document_scanQRCode
-
});
步骤四:通过ready接口处理成功验证
参考官方文档: 通过后台获取js权限签名jsapi_ticket
直接给出后台相关的代码:
1、Token.java
-
-
-
/**
-
* 凭证
-
*
-
*/
-
public class Token {
-
-
// 接口访问凭证
-
private String accessToken;
-
// 凭证有效期,单位:秒
-
private int expiresIn;
-
-
public String getAccessToken() {
-
return accessToken;
-
}
-
-
public void setAccessToken(String accessToken) {
-
this.accessToken = accessToken;
-
}
-
-
public int getExpiresIn() {
-
return expiresIn;
-
}
-
-
public void setExpiresIn(int expiresIn) {
-
this.expiresIn = expiresIn;
-
}
-
-
}
2、JsapiTicket.java
-
-
public class JsapiTicket {
-
-
// 获取到的凭证
-
private String ticket;
-
// 凭证有效期,单位:秒
-
private int expiresIn;
-
-
public String getTicket() {
-
return ticket;
-
}
-
-
public void setTicket(String ticket) {
-
this.ticket = ticket;
-
}
-
-
public int getExpiresIn() {
-
return expiresIn;
-
}
-
-
public void setExpiresIn(int expiresIn) {
-
this.expiresIn = expiresIn;
-
}
-
-
}
3、TokenUtil.java
-
-
-
import java.io.BufferedReader;
-
import java.io.InputStream;
-
import java.io.InputStreamReader;
-
import java.io.OutputStream;
-
import java.net.ConnectException;
-
import java.net.URL;
-
import java.util.ArrayList;
-
import java.util.List;
-
import javax.net.ssl.HttpsURLConnection;
-
import javax.net.ssl.SSLContext;
-
import javax.net.ssl.SSLSocketFactory;
-
import javax.net.ssl.TrustManager;
-
import net.sf.json.JSONException;
-
import net.sf.json.JSONObject;
-
import com.TourGuide.model.JsapiTicket;
-
import com.TourGuide.model.Token;
-
import com.google.gson.Gson;
-
import com.google.gson.JsonObject;
-
import com.google.gson.JsonParser;
-
-
-
public class TokenUtil {
-
-
public final static String appid = "****************";
-
public final static String secret = "****************************";
-
-
// 凭证获取(GET),token_url获取凭证接口的请求地址
-
public final static String token_url = ""
-
+ "grant_type=client_credential&"
-
+ "appid=" + appid + "&"
-
+ "secret=" + secret;
-
-
-
/**
-
* 发送https请求.定义了一个通用的HTTPS请求方法,用于发送HTTPS GET和POST请求
-
* 当调用公众平台的开发接口时,都需要传入接口访问凭证access_token
-
*
-
* @param requestUrl 请求地址
-
* @param requestMethod 请求方式(GET、POST)
-
* @param outputStr 提交的数据
-
* @return
-
*/
-
public static JSONObject getTokenJsonObject(String requestUrl, String requestMethod, String outputStr){
-
-
JSONObject returnData = null;
-
-
try {
-
-
// 创建SSLContext对象,并使用我们指定的信任管理器初始化
-
TrustManager[] tm = {new MyX509TrustManager()};
-
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
-
sslContext.init(null, tm, new java.security.SecureRandom());
-
// 从上述SSLContext对象中得到SSLSocketFactory对象
-
SSLSocketFactory ssf = sslContext.getSocketFactory();
-
-
URL url = new URL(requestUrl);
-
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
-
conn.setSSLSocketFactory(ssf);
-
-
conn.setDoOutput(true);
-
conn.setDoInput(true);
-
conn.setUseCaches(false);
-
// 设置请求方式(GET/POST)
-
conn.setRequestMethod(requestMethod);
-
-
// 当outputStr不为null时向输出流写数据
-
if (null != outputStr) {
-
OutputStream outputStream = conn.getOutputStream();
-
// 注意编码格式
-
outputStream.write(outputStr.getBytes("UTF-8"));
-
outputStream.close();
-
}
-
-
// 从输入流读取返回内容
-
InputStream inputStream = conn.getInputStream();
-
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
-
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
-
String str = null;
-
StringBuffer buffer = new StringBuffer();
-
while ((str = bufferedReader.readLine()) != null) {
-
buffer.append(str);
-
}
-
-
// 释放资源
-
bufferedReader.close();
-
inputStreamReader.close();
-
inputStream.close();
-
inputStream = null;
-
conn.disconnect();
-
-
returnData = JSONObject.fromObject(buffer.toString());
-
} catch (ConnectException ce) {
-
System.out.printf("连接超时:{}", ce);
-
} catch (Exception e) {
-
System.out.printf("https请求异常:{}", e);
-
}
-
-
return returnData;
-
}
-
-
-
/**
-
* 获取接口访问凭证。将得到的json结果转为Token对象
-
* @return
-
*/
-
public static Token getToken(){
-
-
Token token = null;
-
String requestUrl = token_url;
-
// 发起GET请求获取凭证
-
JSONObject returnData = getTokenJsonObject(requestUrl, "GET", null);
-
-
if(null != returnData){
-
-
try {
-
token = new Token();
-
token.setAccessToken(returnData.getString("access_token"));
-
token.setExpiresIn(Integer.parseInt(returnData.getString("expires_in")));
-
-
} catch (Exception e) {
-
token = null;
-
// 获取token失败
-
System.out.printf("获取token失败 errcode:{} errmsg:{}", returnData.get("errcode"),
-
returnData.get("errmsg"));
-
}
-
}
-
-
return token;
-
}
-
-
-
/**
-
* 获取jsapi_ticket
-
*
-
* @param appid 凭证
-
* @param appsecret 密钥
-
* @return
-
*/
-
public static JsapiTicket getJsapiTicket(String accessToken) {
-
-
//获取公众号jsapi_ticket的链接
-
String jsapi_ticket_url = ""
-
+ "access_token=ACCESS_TOKEN&type=jsapi";
-
-
//ticket分享值
-
JsapiTicket jsapiticket = null;
-
-
if(accessToken != null){
-
String requestUrl = jsapi_ticket_url.replace("ACCESS_TOKEN", accessToken);
-
JSONObject jsonObject = getTokenJsonObject(requestUrl, "GET", null);
-
// 如果请求成功
-
if (null != jsonObject) {
-
try {
-
jsapiticket = new JsapiTicket();
-
jsapiticket.setTicket(jsonObject.getString("ticket"));
-
jsapiticket.setExpiresIn(jsonObject.getInt("expires_in"));
-
} catch (JSONException e) {
-
jsapiticket = null;
-
// 获取ticket失败
-
System.out.printf("获取ticket失败 errcode:{} errmsg:{}",
-
jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
-
}
-
}
-
}else{
-
System.out.println("*****token为空 获取ticket失败******");
-
}
-
-
return jsapiticket;
-
}
-
-
}
4、JsSignUtil.java
-
-
import java.io.UnsupportedEncodingException;
-
import java.security.MessageDigest;
-
import java.security.NoSuchAlgorithmException;
-
import java.util.Formatter;
-
import java.util.HashMap;
-
import java.util.Map;
-
import java.util.UUID;
-
-
/**
* 官方给的使用js的验证工具
*
*/
-
public class JsSignUtil {
-
-
public static String accessToken = null;
-
-
public static Map<String, String> sign(String url){
-
-
//获取accessToken
-
accessToken = TokenUtil.getToken().getAccessToken();
-
//获取JsapiTicket
-
String jsapi_ticket =TokenUtil.getJsapiTicket(accessToken).getTicket();
-
-
Map<String, String> ret = new HashMap<String, String>();
-
String nonce_str = create_nonce_str();
-
String timestamp = create_timestamp();
-
String string1;
-
String signature = "";
-
-
//注意这里参数名必须全部小写,且必须有序
-
string1 = "jsapi_ticket=" + jsapi_ticket +
-
"&noncestr=" + nonce_str +
-
"×tamp=" + timestamp +
-
"&url=" + url;
-
// System.out.println("string1="+string1);
-
-
try
-
{
-
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
-
crypt.reset();
-
crypt.update(string1.getBytes("UTF-8"));
-
signature = byteToHex(crypt.digest());
-
}
-
catch (NoSuchAlgorithmException e)
-
{
-
e.printStackTrace();
-
}
-
catch (UnsupportedEncodingException e)
-
{
-
e.printStackTrace();
-
}
-
-
ret.put("url", url);
-
ret.put("jsapi_ticket", jsapi_ticket);
-
ret.put("nonceStr", nonce_str);
-
ret.put("timestamp", timestamp);
-
ret.put("signature", signature);
-
ret.put("appId", "wxd3bda909c7fb1467");
-
-
// System.out.println("1.ticket(原始)="+jsapi_ticket);
-
// System.out.println("2.url="+ret.get("url"));
-
// System.out.println("3.jsapi_ticket(处理后)="+ret.get("jsapi_ticket"));
-
// System.out.println("4.nonceStr="+ret.get("nonceStr"));
-
// System.out.println("5.signature="+ret.get("signature"));
-
// System.out.println("6.timestamp="+ret.get("timestamp"));
-
-
return ret;
-
}
-
-
-
/**
-
* 随机加密
-
* @param hash
-
* @return
-
*/
-
private static String byteToHex(final byte[] hash) {
-
Formatter formatter = new Formatter();
-
for (byte b : hash)
-
{
-
formatter.format("%02x", b);
-
}
-
String result = formatter.toString();
-
formatter.close();
-
return result;
-
}
-
-
/**
-
* 产生随机串--由程序自己随机产生
-
* @return
-
*/
-
private static String create_nonce_str() {
-
return UUID.randomUUID().toString();
-
}
-
-
/**
-
* 由程序自己获取当前时间
-
* @return
-
*/
-
private static String create_timestamp() {
-
return Long.toString(System.currentTimeMillis() / 1000);
-
}
-
}
5、weixinScanController.java
-
import java.util.HashMap;
-
import java.util.Map;
-
import javax.servlet.http.HttpServletRequest;
-
import javax.servlet.http.HttpServletResponse;
-
import org.springframework.stereotype.Controller;
-
import org.springframework.web.bind.annotation.RequestMapping;
-
import org.springframework.web.bind.annotation.ResponseBody;
-
import com.TourGuide.weixin.util.JsSignUtil;
-
-
@Controller
-
public class weixinScanController {
-
-
/**
-
* 微信扫一扫接口的后台处理程序
-
* @param request
-
* @param response
-
* @return
-
* @throws Exception
-
*/
-
@RequestMapping(value = "/weixinScan.do")
-
@ResponseBody
-
public Object weixinScan( HttpServletRequest request,
-
HttpServletResponse response) throws Exception {
-
-
String weburl = request.getParameter("url");
-
-
Map<String, String> resMap = new HashMap<String, String>();
-
resMap = JsSignUtil.sign(weburl);
-
-
return resMap;
-
}
-
-
}
水平有限,如有错误,多多指正
参考:http://blog.csdn.net/u013589542/article/details/54864477
http://blog.csdn.net/f429629227/article/details/53809577
阅读(8580) | 评论(0) | 转发(0) |