• 微信js-sdk config配置的坑次教程适合刚刚接触微信公众号js-sdk的开发人员,教程给新人一些疑惑解答。对于刚刚接触微信的js-sdk的人来说,看官方文档可能对这个到底什么作用还是有点迷糊,官方文档都是使用的具体...

                                                                微信js-sdk config配置的坑

    次教程适合刚刚接触微信公众号js-sdk的开发人员,教程给新人一些疑惑解答。

    对于刚刚接触微信的js-sdk的人来说,看官方文档可能对这个到底什么作用还是有点迷糊,官方文档都是使用的具体步骤,但是作为看文章的人,转发文章的用户具体流程不清楚。下面针对我刚开始搞这个东西的一些疑惑给刚接触的开发者解答一下。

    一个用户打开了一个别的用户发的公众号文章,并且带有缩略图和标题,这是时候用户点开了文章,微信就会对文章里面的js-sdk config 进行验证,确定这篇文章是服务号或者订阅号发的,验证身份。这个时候文章展现,当用户想要转发,点击右上角发送到朋友圈的时候,微信会回调你文章里的js文件,转发到朋友圈的方法上,这个方法是js-sdk 固定的方法,点击转发就成功了,这个就是js-sdk的作用,识别你文章的身份,转发文章回调固定的函数,告知你结果。(在此不得不佩服微信的开发人员,把一个软件,做体验做市场,还能在软件基础上再做开发市场,牛逼啊)

    下面上代码:你需要做的东西有一个文章的html页面,在页面导入微信下载的js-sdk的包,

    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title><script language="javascript" type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
    <script language="javascript" type="text/javascript" src="__PUBLIC__/js/jquery-1.8.3.min.js"></script>
    
    <script language="javascript" type="text/javascript" src="__PUBLIC__/js/sha1.js"></script>
    <script language="javascript" type="text/javascript" src="__PUBLIC__/js/weixinjsdata.js"></script>

    导入有顺序,先js-sdk,再jquery,再sha1用来生成加密的文件,自己写的微信生成验证信息各种函数的js文件

    下面是weixinjsdata.js文件,这里感谢一位程序员分享的代码,我照搬他的,针对我的修改了一点

    var wxdata={
    	wx_account:new Array(4),
    	wx_share:new Array(4),
    	wx_myuser:new Array("wxxxxxxx3e856e","22851xxxxxxxxxxxxxxxx5121dcd"),
    	
    	
    	
    	access_token:"", //凭证
    	token_expires_in:"",  //凭证过期时间单位s
    	jsapi_ticket:"",  //凭证
    	ticket_expires_in:"",    //凭证过期时间
    
    	//获取jsapi_ticket 
    	//url:"https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+wxdata.access_token+"&type=jsapi",
    	get_jsapi_ticket:function(){
    		
    		$.ajax({
    			type:"GET",
    			url:"/index.php/get_ticket",
    			dataType:"json",
    			cache:false,
    			async:false,
    			success:function(msg){
    				 /*  
                    { 
                        "errcode":0, 
                        "errmsg":"ok", 
                        "ticket":"e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA", 
                        "expires_in":7200 
                    }  
                */  
    			
    			if(msg.errcode==0){
    				wxdata.jsapi_ticket=msg.ticket;  //需要缓存,存活时间为ticket_expires_in
    				//wxdata.ticket_expires_in=msg.expires_in;
    				//wxdata.timestamp=msg.timestam;
    				console.log("get jsapi_ticket success");
    			}else{
    				console.log("get jsapi_ticket fail");
    			}
    			
    			},
    			error:function(msg){
    				alert("get jsapi_ticket error!!");
    			}
    			
    			
    		});
    	},
    	//数据签名
    	create_signature:function(noncestr,ticket,timestamp,url){
    		var signature="";
    		//这里参数的顺序要按照key值ascii 码升序排序
    	var s="jsapi_ticket="+ticket+"&noncestr="+noncestr+"×tamp="+timestamp+"&url="+url;
    	//console.log();
    	return hex_sha1(s);
    	},
    	//自定义创建随机串
    	create_noncestr:function(){
    		var str="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    		var val="";
    		for(var i=0;i<16;i++){
    			val+=str.substr(Math.round((Math.random()*10)),1);
    		}
    		return val;
    	},
    	//自定义创建时间戳
    	create_timestamp:function(){
    		//return new Date().getSeconds();
    		return Date.parse(new Date()).toString().substr(0,10);
    		
    	}
    	
    	
    }
    
    wxdata.get_jsapi_ticket();
    var timestamp=wxdata.create_timestamp();
    var noncestr=wxdata.create_noncestr();
    var url=window.location.href.split('#').toString();
    
    
    wxdata.wx_account[0]=wxdata.wx_myuser[0];
    wxdata.wx_account[1]=timestamp;
    wxdata.wx_account[2]=noncestr;
    wxdata.wx_account[3]=wxdata.create_signature(noncestr,wxdata.jsapi_ticket,timestamp,url);
    wxdata.wx_share[0]="http://xxxxxxxxxm/Public/images/zhuanshare.png";
    wxdata.wx_share[1]="http://wxxxx/index.php";
    
    wxdata.wx_share[2]="";  //share_desc
    wxdata.wx_share[3]="";  //share_tilte

    这里说一下,上面是定义变量用来保存一些数据,后面html使用,中间是一些函数,因为要实现js-sdk的功能要获得微信的ticket凭证才行,这是条件之一,先获取token,再获取ticket,我写了一个js的ajax,连接服务器的一个方法,先获取token,再通过token获取ticket一个方法搞定,如果你的转发多,怕ticket使用次数问题,可以用数据库存一下,判断秒数,重用,

    下面是服务器端代码

    //返回token
    		public function get_ticket(){
    			
    			$appid="wXXXXXXXXXXX8f73e856e";
    			$secret="2285XXXXXXXXXXXXXXc9512XXXXXX";
    			
    			$url="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$appid."&secret=".$secret;
    			
    			$ch=curl_init();
    			curl_setopt($ch,CURLOPT_URL,$url);
    			curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
    			curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
    			curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);
    			$dd=curl_exec($ch);
    			curl_close($ch);
    			
    			$access=json_decode($dd,true);
    $url="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=".$access['access_token']."&type=jsapi";
    			$ca=curl_init();
    			curl_setopt($ca,CURLOPT_URL,$url);
    			curl_setopt($ca,CURLOPT_RETURNTRANSFER,1);
    			curl_setopt($ca,CURLOPT_SSL_VERIFYPEER,false);
    			curl_setopt($ca,CURLOPT_SSL_VERIFYHOST,false);
    			$da=curl_exec($ca);
    			curl_close($ca);
    			
    			$ticket=json_decode($da,true);
    			//$ticket['timestam']=time();
    			$a->where("category='ticket'")->setField("token",$ticket['ticket']);
    			$a->where("category='ticket'")->setField("expires",$atime);
    			
    		}else{
    			$ticket['errcode']=0;
    			$ticket['ticket']=$da['token'];
    		}
    			$this->ajaxReturn($ticket);
    			
    		}

    所有具备上最后的验证,

    var $wx_account=wxdata.wx_account,
    	$wx_share=wxdata.wx_share;
    
    
    
     wx.config({
    	
    	 debug:false, //开启调试
    	 appId:'wxXXXXXXXXf7XXXXXe',
    	 timestamp:$wx_account[1],  //生成签名的时间戳
    	 nonceStr:$wx_account[2],
    	 signature:$wx_account[3],  //签名
    	 jsApiList:[
    	 'onMenuShareTimeline',
    	  'onMenuShareAppMessage',
    	 'onMenuShareQQ',
    	 'onMenuShareWeibo'
    	 ]  //JS接口列表
     });

    本篇文章的重点 开发的时候debug:true ,改成true,自己手机微信扫一扫,因为一些现实原因微信浏览器会绝对的缓存网页的文件,js,css,img都会缓存,即使你设置了它依然会缓存。这个大坑,搞得我全网搜为什么不能验证通过,其实已经通过了,但是很多人分享的都没说这个问题,这是很严重的问题,耽误了我一天的时间,所以每次修改文件了都要清微信浏览器的缓存,方法是 https://link.zhihu.com/?target=http%3A//debugx5.qq.com 这个链接复制到一些生成二维码的网站生成二维码,用微信扫一扫,打开,滑到页面下面,清空浏览器的缓存,这个浏览器打开你的页面都是新的,从新下载。不然老是以为没有验证成功。

    希望文章对新人有帮助,祝大家开发的时候,遇到奇怪bug,稳住自己的血压,找原因。。



    展开全文
  • 话不多说,首先第一步,获取config需要的参数 appid,noncestr ,timestamp ,url ,signature ... * 微信配置获取config * * @param request * @return */ @RequestMapping(value = "/config", me...
    话不多说,首先第一步,获取config需要的参数  
    appid,noncestr ,timestamp ,url ,signature
    1.编写controller

     /**
         * 微信配置获取config
         *
         * @param request
         * @return
         */
        @RequestMapping(value = "/config", method = RequestMethod.POST)
        public MpFFPhoneOrderResponse getWxConfig(HttpServletRequest request) {
            MpFFPhoneOrderResponse response = new MpFFPhoneOrderResponse();//这个只是定义返回的参数,自己根据需要
            String url = request.getRequestURL().toString() + "/";
            try {
                JsSdk sign = Sign.sign(url);
                response.setConfigInfo(JSONObject.toJSONString(sign));
            } catch (Exception e) {
                LOG.info(e.getMessage());
            }
            return success(response);
        }
     jsSdk
    public class Sign {
        /**
         * jsSdk 获取微信config
         *
         * @param url
         * @return
         */
        public static JsSdk sign(String url) {
            String jsapi_ticket = JsapiTicketUtil.getJsapiTicket();
            JsSdk jsSdk = new JsSdk();
            jsSdk.setAppid(WXAuthUtil.getAPPID());
            jsSdk.setUrl(url);
            String nonce_str = create_nonce_str();
            jsSdk.setNoncestr(nonce_str);
            String timestamp = create_timestamp();
            jsSdk.setTimestamp(timestamp);
            String signature = "";
            //注意这里参数名必须全部小写,且必须有序
            String 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());
                jsSdk.setSignature(signature);
            } catch (NoSuchAlgorithmException e) {
                jsSdk = null;
                e.printStackTrace();
            } catch (UnsupportedEncodingException e) {
                jsSdk = null;
                e.printStackTrace();
            }
            return jsSdk;
        }
    
        /**
         * 生成随机数
         *
         * @return
         */
        private static String create_nonce_str() {
            return UUID.randomUUID().toString().substring(0, 20);
        }
    
        /**
         * 当前日期字符串生成
         *
         * @return
         */
        private static String create_timestamp() {
            return Long.toString(System.currentTimeMillis() / 1000);
        }
    
        /**
         *
         * @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;
        }
    }
    获取票据 jsapi_ticket
    public class JsapiTicketUtil {
        public static final Logger LOG = LoggerFactory.getLogger(JsapiTicketUtil.class);
    
        public static String getJsapiTicket() {
            String requestUrl = "https://api.weixin.qq.com/cgi-bin/token?";
            String params = "grant_type=client_credential&appid=" + WXAuthUtil.APPID + "&secret=" + WXAuthUtil.APPSECRET + "";
            String result = httpGet(requestUrl + params);
            String access_token = JSONObject.parseObject(result).getString("access_token");
            requestUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?";
            params = "access_token=" + access_token + "&type=jsapi";
            result = httpGet(requestUrl + params);
            String jsapi_ticket = JSONObject.parseObject(result).getString("ticket");
            return jsapi_ticket;
        }
    
        /**
         * post请求
         * @param url
         * @return
         */
        public static String httpPost(String url) {
            //post请求返回结果
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpPost method = new HttpPost(url);
            String str = "";
            try {
                HttpResponse result = httpClient.execute(method);
                url = URLDecoder.decode(url, "UTF-8");
                /**请求发送成功,并得到响应**/
                if (result.getStatusLine().getStatusCode() == 200) {
                    try {
                        /**读取服务器返回过来的json字符串数据**/
                        str = EntityUtils.toString(result.getEntity());
                    } catch (Exception e) {
                        LOG.error("post请求提交失败:" + url, e);
                    }
                }
            } catch (IOException e) {
                LOG.error("post请求提交失败:" + url, e);
            }
            return str;
        }
    
        /**
         * get 请求、
         * @param url
         * @return
         */
        public static String httpGet(String url) {
            //get请求返回结果
            String strResult = null;
            try {
                DefaultHttpClient client = new DefaultHttpClient();
                //发送get请求
                HttpGet request = new HttpGet(url);
                HttpResponse response = client.execute(request);
    
                /**请求发送成功,并得到响应**/
                if (response.getStatusLine().getStatusCode() == org.apache.http.HttpStatus.SC_OK) {
                    /**读取服务器返回过来的json字符串数据**/
                    strResult = EntityUtils.toString(response.getEntity());
                } else {
                    LOG.error("get请求提交失败:" + url);
                }
            } catch (IOException e) {
                LOG.error("get请求提交失败:" + url, e);
            }
            return strResult;
        }
    }
    
    config需要的javabean
    public class JsSdk {
    
        private String appid;
        //随机数
        private String noncestr;
        //时间戳
        private String timestamp;
        //授权url
        private String url;
        //签名
        private String signature;
    
        public String getAppid() {
            return appid;
        }
    
        public void setAppid(String appid) {
            this.appid = appid;
        }
    
        public String getNoncestr() {
            return noncestr;
        }
    
        public void setNoncestr(String noncestr) {
            this.noncestr = noncestr;
        }
    
        public String getTimestamp() {
            return timestamp;
        }
    
        public void setTimestamp(String timestamp) {
            this.timestamp = timestamp;
        }
    
        public String getUrl() {
            return url;
        }
    
        public void setUrl(String url) {
            this.url = url;
        }
    
        public String getSignature() {
            return signature;
        }
    
        public void setSignature(String signature) {
            this.signature = signature;
        }
    
    }

    到这里后台基本上差不多可以结束了,结合上篇文章,支付所需要的参数,接下来就是前台操作:

    1.引用js

    <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>

     wxconfig: function () {
                        var _this = this;
                        $.ajax({
                            type: "post",
                            dataType: "json",
                            traditional: true,
                            url: 'xxxx',//config后台路径
                            data: '',
                            success: function (data) {
                                if (data.code == 'ok') {
                                    var configInfo = data.configInfo;
                                    var configJson = JSON.parse(configInfo);
                                    wx.config({
                                        debug: false,
                                        appId: configJson.appid,
                                        timestamp: configJson.timestamp,
                                        nonceStr: configJson.noncestr,
                                        signature: configJson.signature,
                                        jsApiList: ['scanQRCode', 'onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareWeibo', 'onMenuShareQZone', 'chooseWXPay']
                                    });
                                } else {
                                    console.log("验证失败");
                                }
                            }
    
                        })
                    },

    2.config成功之后直接调用微信支付

     wxPay: function (paydata) {
                        this.wxconfig();
                        wx.ready(function () {
                            // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
                            var dataJson = JSON.parse(paydata);
                            //进行微信支付
                            wx.chooseWXPay({
                                timestamp: dataJson.timeStamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
                                nonceStr: dataJson.nonceStr, // 支付签名随机串,不长于 32 位
                                package: dataJson.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***)
                                signType: dataJson.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
                                paySign: dataJson.paySign, // 支付签名
                                success: function (res) {
                                    // 支付成功后的回调函数
                                    if (res.errMsg == "chooseWXPay:ok") {
                                        weui.alert('支付成功');
                                     
                                        // 支付成功
                                        // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回    ok,但并不保证它绝对可靠。
                                    } else {
                                        weui.alert('支付失败');
                                    }
                                }
                            });
                        })
                    },
    到这里基本上就非常nice了,回调支付成功,如果中间有什么问题没有成功可以随时留言,谢谢。不喜勿喷。


    展开全文
  • 前端开发工程师和关注前端开发的开发者们在2015年中肯定被腾讯的JSSDk引爆过,搞APP的、搞前端的甚至是是搞后端的都跑过来凑热闹,一时之间也把微信JSSDK捧得特别牛逼,但是在我们的技术眼里它的实现原理和根本是不...

    前端开发工程师和关注前端开发的开发者们在2015年中肯定被腾讯的JSSDk引爆过,搞APP的、搞前端的甚至是是搞后端的都跑过来凑热闹,一时之间也把微信JSSDK捧得特别牛逼,但是在我们的技术眼里它的实现原理和根本是不能够被改变的,这篇文章就不对其js的实现做任何评价和解说了(因为我也不是很懂,哈哈),这里要说的是它的config配置实现,参考文档:http://mp.weixin.qq.com/wiki/11/74ad127cc054f6b80759c40f77ec03db.html  !

    微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包,通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验;本篇将面向网页开发者介绍微信JS-SDK如何使用及相关注意事项!JSSDK使用步骤:

    • 步骤一:在微信公众平台绑定安全域名

    • 步骤二:后端接口实现JS-SDK配置需要的参数

    • 步骤三:页面实现JS-SDk中config的注入配置,并实现对成功和失败的处理

    (一)在微信公众平台绑定安全域名

    先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”(如下图),如果需要使用支付类接口,需要确保支付目录在支付的安全域名下,否则将无法完成支付!(注:登录后可在“开发者中心”查看对应的接口权限)

     1.png

    (二)后端接口实现JS-SDK配置需要的参数

    1
    2
    3
    4
    5
    6
    7
    8
    wx.config({
        debug: true// 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
        appId: ''// 必填,公众号的唯一标识
        timestamp: , // 必填,生成签名的时间戳
        nonceStr: ''// 必填,生成签名的随机串
        signature: '',// 必填,签名,见附录1
        jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
    });

    我们查看js-sdk的配置文档和以上的代码可以发现config的配置需要4个必不可少的参数appId、timestamp、nonceStr、signature,这里的signature就是我们生成的签名!

    生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket ,所以这里我们将jsapi_ticket的获取放到定时任务中,因为它和token的生命周期是一致的,所以在这里我们将他们放到一起,将原有的定时任务中获取token的代码做如下修改:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    package com.cuiyongzhi.wechat.common;
     
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.Map;
     
    import net.sf.json.JSONObject;
     
    import com.cuiyongzhi.web.util.GlobalConstants;
    import com.cuiyongzhi.wechat.util.HttpUtils;
     
    /**
     * ClassName: WeChatTask
     * @Description: 微信两小时定时任务体
     * @author dapengniao
     * @date 2016年3月10日 下午1:42:29
     */
    public class WeChatTask {
        /**
         * @Description: 任务执行体
         * @param @throws Exception
         * @author dapengniao
         * @date 2016年3月10日 下午2:04:37
         */
        public void getToken_getTicket() throws Exception {
            Map<String, String> params = new HashMap<String, String>();
            //获取token执行体
            params.put("grant_type""client_credential");
            params.put("appid", GlobalConstants.getInterfaceUrl("appid"));
            params.put("secret", GlobalConstants.getInterfaceUrl("AppSecret"));
            String jstoken = HttpUtils.sendGet(
                    GlobalConstants.getInterfaceUrl("tokenUrl"), params);
            String access_token = JSONObject.fromObject(jstoken).getString(
                    "access_token"); // 获取到token并赋值保存
            GlobalConstants.interfaceUrlProperties.put("access_token", access_token);
             
            //获取jsticket的执行体
            params.clear();
            params.put("access_token", access_token);
            params.put("type""jsapi");
            String jsticket = HttpUtils.sendGet(
                    GlobalConstants.getInterfaceUrl("ticketUrl"), params);
            String jsapi_ticket = JSONObject.fromObject(jsticket).getString(
                    "ticket"); 
            GlobalConstants.interfaceUrlProperties
            .put("jsapi_ticket", jsapi_ticket); // 获取到js-SDK的ticket并赋值保存
             
            System.out.println("jsapi_ticket================================================" + jsapi_ticket);
            System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())+"token为=============================="+access_token);
     
        }
     
    }

    然后我们根据【JS-SDK使用权限签名算法】对参数进行签名得到signature,这里的url必须采用前端传递到后端,因为每次的url会有所变化,如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    package com.cuiyongzhi.wechat.common;
     
    import java.security.MessageDigest;
    import java.util.Formatter;
    import java.util.HashMap;
    import java.util.UUID;
    import com.cuiyongzhi.web.util.GlobalConstants;
     
     
    /**
     * ClassName: JSSDK_Config
     * @Description: 用户微信前端页面的jssdk配置使用
     * @author dapengniao
     * @date 2016年3月19日 下午3:53:23
     */
    public class JSSDK_Config {
     
        /**
         * @Description: 前端jssdk页面配置需要用到的配置参数
         * @param @return hashmap {appid,timestamp,nonceStr,signature}
         * @param @throws Exception   
         * @author dapengniao
         * @date 2016年3月19日 下午3:53:23
         */
        public static HashMap<String, String> jsSDK_Sign(String url) throws Exception {
            String nonce_str = create_nonce_str();
            String timestamp=GlobalConstants.getInterfaceUrl("timestamp");
            String jsapi_ticket=GlobalConstants.getInterfaceUrl("jsapi_ticket");
            // 注意这里参数名必须全部小写,且必须有序
            String  string1 = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce_str
                    "&timestamp=" + timestamp  + "&url=" + url;
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(string1.getBytes("UTF-8"));
            String signature = byteToHex(crypt.digest());
            HashMap<String, String> jssdk=new HashMap<String, String>();
            jssdk.put("appId", GlobalConstants.getInterfaceUrl("appid"));
            jssdk.put("timestamp", timestamp);
            jssdk.put("nonceStr", nonce_str);
            jssdk.put("signature", signature);
            return jssdk;
     
        }
         
        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();
        }
     
    }

    然后我们将后端签名的方法集成到Controller层,形成代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    package com.cuiyongzhi.wechat.controller;
     
    import java.util.Map;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import com.cuiyongzhi.Message;
    import com.cuiyongzhi.wechat.common.JSSDK_Config;
     
    /**
     * ClassName: WeChatController
     * @Description: 前端用户微信配置获取
     * @author dapengniao
     * @date 2016年3月19日 下午5:57:36
     */
    @Controller
    @RequestMapping("/wechatconfig")
    public class WeChatController {
     
        /**
         * @Description: 前端获取微信JSSDK的配置参数
         * @param @param response
         * @param @param request
         * @param @param url
         * @param @throws Exception
         * @author dapengniao
         * @date 2016年3月19日 下午5:57:52
         */
        @RequestMapping("jssdk")
        public Message JSSDK_config(
                @RequestParam(value = "url", required = true) String url) {
            try {
                System.out.println(url);
                Map<String, String> configMap = JSSDK_Config.jsSDK_Sign(url);
                return Message.success(configMap);
            catch (Exception e) {
                return Message.error();
            }
     
        }
     
    }

    到这里我们后端对jssdk的签名参数的封装就基本完成了,下一步就只需要我们前端调用就可以了!

    (三)页面实现JS-SDk中config的注入配置,并实现对成功和失败的处理

    在第二步中我们将后端接口代码完成了,这里新建jssdkconfig.jsp,在jsp页面用ajax方式获取并进行配置,并开启debug模式,打开之后就可以看到配置是否成功的提示,简单代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html >
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta name="viewport" content="width=device-width" />
    <title>JSSDk配置</title>
    <script type="text/javascript">
        function jssdk() {
            $.ajax({
                url : "http://wechat.cuiyongzhi.com/wechatconfig/jssdk",
                type : 'post',
                dataType : 'json',
                contentType : "application/x-www-form-urlencoded; charset=utf-8",
                data : {
                    'url' : location.href.split('#')[0]
                },
                success : function(data) {
                    wx.config({
                        debug : true,
                        appId : data.data.appId,
                        timestamp : data.data.timestamp,
                        nonceStr : data.data.nonceStr,
                        signature : data.data.signature,
                        jsApiList : [ 'checkJsApi', 'onMenuShareTimeline',
                                'onMenuShareAppMessage', 'onMenuShareQQ',
                                'onMenuShareWeibo', 'hideMenuItems',
                                'showMenuItems', 'hideAllNonBaseMenuItem',
                                'showAllNonBaseMenuItem', 'translateVoice',
                                'startRecord', 'stopRecord', 'onRecordEnd',
                                'playVoice', 'pauseVoice', 'stopVoice',
                                'uploadVoice', 'downloadVoice', 'chooseImage',
                                'previewImage', 'uploadImage', 'downloadImage',
                                'getNetworkType', 'openLocation', 'getLocation',
                                'hideOptionMenu', 'showOptionMenu', 'closeWindow',
                                'scanQRCode', 'chooseWXPay',
                                'openProductSpecificView', 'addCard', 'chooseCard',
                                'openCard' ]
                    });
                }
            });
        }
     
        function isWeiXin5() {
            var ua = window.navigator.userAgent.toLowerCase();
            var reg = /MicroMessenger\/[5-9]/i;
            return reg.test(ua);
        }
     
        window.onload = function() {
            //     if (isWeiXin5() == false) {
            //           alert("您的微信版本低于5.0,无法使用微信支付功能,请先升级!");
            //         }
            jssdk();
        };
    </script>
    </head>
    <body>
    </body>
    </html>

    最后我们运行代码,查看运行结果:

    2.jpg

    如果提示是这样,那么标识我们的配置是成功的,那么到这里微信jssdk的配置就基本完成了,下一篇讲述【微信web开发者工具】的使用,欢迎你的翻阅,如有疑问可以留言讨论!

    展开全文
  • vue.js引入jssha后,用于获取微信公众号config接口注入权限验证的签名代码,官网下载的签名,本人无法使用,经过修改可用。
  • 公司需要微信支付现不到镇的是非常的麻烦。然后呢那个要怎么申请我就不写了。因为不是我负责的所以我就记录微信支付开发就好了。自己也记录一下以后要开发好下手 。 1. 到这里下载sdk  版本本V3 : ...
            公司需要微信支付现不到镇的是非常的麻烦。然后呢那个要怎么申请我就不写了。因为不是我负责的所以我就记录微信支付开发就好了。自己也记录一下以后要开发好下手 。
    1. 到这里下载sdk
            版本本V3 : http://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=11_1
    2. 下载好后修改配置文件位于: lib/WxPay.Config.php 然后修改 指定的参数
           APPID:绑定支付的APPID(必须配置,开户邮件中可查看)
            MCHID:商户号(必须配置,开户邮件中可查看)
            KEY:商户支付密钥,参考开户邮件设置(必须配置,登录商户平台自行设置)设置地址:

            https://pay.weixin.qq.com/index.php/account/api_cert
           APPSECRET:公众帐号secert (登录公众平台,进入开发者中心 - AppSecret )
    3.到 https://pay.weixin.qq.com/index.php/account/api_cert 这个位置下载证书 然后解压 apiclient_cert.pem和

            apiclient_key.pem 放到这个 cert 文件夹
    4. 到微信公众平台 左边栏 微信支付 - 开发配置
            支付测试
            测试目录 为你的域名(注意如果选择了http:// 那么你就直接输入域名就好了 )
            测试白名单 为 你要测试的微信帐号(app端的 我 - 点击头像 - 微信号 没有的话自己设置一下)
            如果配备错误到支付的时候会显示 system:access_denied
    5.开发者中心 - 网页授权获取用户基本信息 - 修改(写上你的域名) 

    PS:位于doc/README.doc 这个是基本文件结构文档大伙可以看看 如果出现了 redirect uri 参数错误 这个错误那么

            请看第4步和第5步 重新设置一下

    原文地址:http://alzhai.com/post-697.html

    展开全文
  • 1.在学习微信公众号开发,因为是屌丝,没办法只能搞内网穿透,配置微信公众号的接口配置,一直显示匹配失败。做个流程笔记,以备于下次忘记。 第一步,写代码创建一个工程,创建app.js.基于koa。安装依赖koa(参考...

    1.本文是在学习网络视频做的总结

    1.在学习微信公众号开发,因为是屌丝,没办法只能搞内网穿透,配置微信公众号的接口配置,一直显示匹配失败。做个流程笔记,以备于下次忘记。

    第一步,写代码创建一个工程,创建app.js.基于koa。安装依赖koa(参考廖老师的安装koa)和sha1.

    var Koa = require('koa')
    var sha1 = require('sha1')
    var config= {
        wechat:{
         appID:'wxf56df97c0c8a4d115',
         appSecret:'ed3528ca1ac2133243e3fac9918fb714b',
         token:'dhadgkadgajkdgasfdszsafgvdfnss',
        }
     }
     var app = new Koa()
     app.use(function *(next){
        console.log(this.query)
        var token= config.wechat.token
            var signature = this.query.signature
            var nonce = this.query.nonce
            var timestamp = this.query.timestamp
            var echostr = this.query.echostr
            var str = [token,timestamp,nonce].sort().join('')
            var sha = sha1(str) 
            if (sha===signature) {
                this.body = echostr + ''
            
            } else {
                this.body = 'wrong'
            }
     })
     app.listen(3104)
     console.log("listening:3104")

    注意appid和appSecret都是来自于测试接口。

    第二:开启 node app.js。(浏览器中输入http://localhost:3104/?a=1),控制台打印{"a":1},此时表示koa监听浏览器成功。

    第三步开启ngrok代理。

    填写微信公众号平台的接口验证,

    需要注意的当点击提交按钮的时候,实际上经历的是微信公众平台给你填写的内网穿透服务器地址发送了一个消息,而内网服务器映射地址到本地的主机浏览器监听3104端口。

    展开全文
  • 问题很简单,只是不好找。 在配置微信分享内容的link里,链接要写全; 如http://www.baidu.com/index.html; 如果不加http://就会faild
  • 在上篇文章实现微信扫码获取带指定参数时,微信公众号后台启用了服务器配置,导致之前设置好的微信自定义菜单失效。 开启了服务器配置,就无法用之前的方式在微信公众平台配置自定义菜单 此时,我们要通过接口来...
  • 检查appId和js接口安全域名配置是否正确 检查IP白名单设置 排查 1.确认签名算法正确,可用http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign 页面工具进行校验。通过测试工具拿到的signature值和用签名...
  • 微信接口配置信息修改是微信测试开发经常用到的,但是本人在最近学习中经常配置不成功,而且token并没有错误,经过了多次查看代码,甚至将微信官方代码放上去配置仍然不行后,终于在茫茫百度中找到了答案,没错,那...
  • 微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包。 通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、...
  • 企业微信JS-SDK是企业微信面向网页开发者提供的基于企业微信内的网页开发工具包。 通过js-sdk可以在企业微信内实现众多功能,如调出通讯录、调出摄像头、隐藏部分按钮等。 使用js-sdk分为三步: 1.开发页面引入JS...
  • 微信开发之JSSDK调用

    2016-11-22 17:03:13
    所以对PHP微信开发只能看懂思路。更有的是,网上一些微信开发视频,也是和PHP有关的,关于用Java开发的甚少。 无奈之下,我只好苦啃微信开发文档。大家都知道,微信官方给的开发文档真的有点那个啥,
  • 微信开发中遇到,当把secondShare里面的wx.config--debug设成true之后,通过手机端访问如果出问题会alert出来。 我们开发过程中,弹出了config:invalid url domain错误, 此错误原因 是微信公众号后台配置的微信...
  • var link = location.href; $.ajax({  url: "/WxJSSDK/WxJS_SDK.aspx/GetInfoMation",//后台给你提供的接口  type: "Post",  data: "{ 'url': '"+link+"' }",  async: false,  contentType: "application/json;...
  • 微信公众号开发-服务器配置 最近在进行公司的微信公众号和小程序的开发,由于都是由本人独立研发,所以框架和接口都要自己去搭去写,因此想把相关接口做完之后做一些记录,如今闲来无事就总结下相关接口,本篇内容为...
  • config:invalid url donmain 首先...以上就是症状,估计都挺崩溃的,如果你是第一次搞这些东西,并且没人指导那简直就是蛋疼,微信那帮孙子写的文档大家都是了解的 ,想当年我们搞个微信支付配置,按照微信的文档全公司
1 2 3 4 5 ... 20
收藏数 4,238
精华内容 1,695