微信开发系列(六)_js调用微信扫码

项目里面需要用到用户通过网址来进行授权
需要用到微信的扫码(请用微信打开
看效果
 http://lg.kezir.com/testSaoMa/jsDemo.html?a=1
微信JS-SDK说明文档

概述

微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包。

通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验。

此文档面向网页开发者介绍微信JS-SDK如何使用及相关注意事项。

JSSDK使用步骤

步骤一:绑定域名

1先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。

微信开发系列(六)_js调用微信扫码_第1张图片


微信开发系列(六)_js调用微信扫码_第2张图片

注意不需要写端口号

2可以看到图中第三步要将

放到服务器的tomcat根目录下 注意放在

 /usr/java/tomcat7/webapps/ROOT目录下就可以保存

【因为默认访问的就是root目录】

步骤二:引入JS文件

在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.0.0.js

如需使用摇一摇周边功能,请引入 http://res.wx.qq.com/open/js/jweixin-1.1.0.js

备注:支持使用 AMD/CMD 标准模块加载方法加载

我就直接下载了(哈哈)

步骤三:通过config接口注入权限验证配置

所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)。

wx.config({

    debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。

    appId: '', // 必填,公众号的唯一标识

    timestamp: , // 必填,生成签名的时间戳

    nonceStr: '', // 必填,生成签名的随机串

    signature: '',// 必填,签名,见附录1

    jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2

});

步骤四:通过ready接口处理成功验证

wx.ready(function(){

    // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。

});

步骤五:通过error接口处理失败验证

wx.error(function(res){

    // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。

});

具体的实现
新建项目(项目的目录)
微信开发系列(六)_js调用微信扫码_第3张图片
将相应的js放进去不要忘了init.js
一:写jsDemo.html

 
   

微信JS-SDK Demo


    
      点击扫描二维码
      
    
  


上面颜色不同的部分就是配置微信的过程那是固定不变的
二:写服务器获取相应的数据
我们现在要管的就是数据的得到 就是获取它所需要的
 appId // 必填,公众号的唯一标识 不用获取直接去微信拿
 timestamp // 必填,生成签名的时间戳不用获取程序可以生成
 nonceStr  // 必填,生成签名的随机串 不用获取程序可以生成
 signature// 必填,签名 这是我们要获取的
 
   
而这些我就直接在服务器端获取得了
首先 appId 直接去你的微信开发者平台上面找    注意是订阅号的appid不是测试号的的appid)
微信开发系列(六)_js调用微信扫码_第4张图片
其次获 timestamp nonceStr  signature
 
   
微信JSSdk里面给出了一个方法 不需要导入任何的包 能获得 timestamp nonceStr
package com.weixin.util;
import java.util.UUID;

import com.alibaba.fastjson.JSONObject;

import java.util.Map;
import java.util.HashMap;
import java.util.Formatter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.io.UnsupportedEncodingException;  

class Sign {
    /**
     * 获取nonce_str timestamp signature的方法
     * @param jsapi_ticket 传入的ticket
     * @param url 传入需要在微信中打开扫码的url
     * @return map
     */
    public static Map sign(String jsapi_ticket, String url) {
        Map ret = new HashMap();
        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;

        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);

        return ret;
    }

    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;
    }

    private static String create_nonce_str() {
        return UUID.randomUUID().toString();
    }

    private static String create_timestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }
}

三:写Servlet(spring里面的Controller也行)来控制
Servlet代码
package com.weixin.util;

import java.io.IOException;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.gson.annotations.Since;

/**
 * Servlet implementation class getticket
 */
@WebServlet("/getticket")
public class getticket extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public getticket() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
//        response.getWriter().append("Served at: ").append(request.getContextPath());
        doPost(request, response);
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
//        doGet(request, response);
          String jsapi_ticket = HttpUtil.getJsTicket();
            String jsonstr = "{\"appId\":\""+WX_Token.APPID+"\",";
            // 注意 URL 一定要动态获取
            String url = " http://lg.kezir.com/testSaoMa/jsDemo.html";
            Map ret = Sign.sign(jsapi_ticket, url);
            for (Map.Entry entry : ret.entrySet()) {
                jsonstr += "\""+entry.getKey() + "\":\"" + entry.getValue()+"\",";
            }
            jsonstr = jsonstr.substring(0,jsonstr.length()-1);
            jsonstr +="}";
            System.out.println(jsonstr);
           response.getWriter().println(jsonstr);
    }

}

图解
微信开发系列(六)_js调用微信扫码_第5张图片
现在就只剩下方法Http.getJsTicket()没讲了(url直接设置分享的网址就行了)
这是用来获取ticket的
1先根据appId和appSecret获取access_token
2再根据access_token获取ticket

获取ticket接口调用请求说明

http请求方式: GET
https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=wx_card
package com.weixin.util;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
public class HttpUtil {
    private static String access_Token = "";
    /**
     * get请求获取网址
     * @param url
     * @param charset
     * @return
     */
    public static String sendGet(String url,String charset){
        CloseableHttpClient httpClient=HttpClients.createDefault();
        HttpGet get=new HttpGet(url);
        CloseableHttpResponse response = null;  
        String result=null;
        try {
            response=httpClient.execute(get);
            HttpEntity entity=response.getEntity();
            //System.out.println(entity.getContentType().getValue());
            result=EntityUtils.toString(entity,charset);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return result;
    }
    //获取tickect
    public static String getJsTicket(){
        JSONObject jsonObject = new JSONObject();
        String ticket = "";
        if(access_Token ==""){//如果是第一次获取就直接去请求新的
            ticket = getTicket();
        }else{//否则就请求旧的
            String result = sendGet(" https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+access_Token+"&type=jsapi","UTF-8");
            jsonObject = JSON.parseObject(result);
            String resultCode = jsonObject.getString("errcode");
            if(resultCode !="0"){//请求旧的如果不行
                ticket = getTicket();//再去请求新的
            }
            else{//如果请求的新的ok
                ticket = jsonObject.getString("ticket");//直接获取
            }
        }
        return ticket;
    }
    /**
     * 获取最新的ticket
     * @return
     */
    public static String getTicket(){
        JSONObject jsonObject = new JSONObject();
        access_Token = WX_Token.getAccessTokenByNet().getAccess_token();//获取 Access_token代码就不贴了
        String result = sendGet(" https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+WX_Token.getAccessTokenByNet().getAccess_token()+"&type=jsapi","UTF-8");
        jsonObject = JSON.parseObject(result);
        return jsonObject.getString("ticket");
    }
}

你可能感兴趣的:(微信开发)