1. 程式人生 > >網頁分享到微信自定義標題,內容和圖片

網頁分享到微信自定義標題,內容和圖片

網頁分享到微信中自定義標題,內容和圖片

隨便說說:

網頁現在也可以通過微信中直接開啟,這就是用到時微信的瀏覽器,也可以通過微信瀏覽器中右上角進行分享到朋友,朋友圈,QQ等。這是需要微信的JSSDK的機制所以還是要進行一些配置才可以,而這些配置是需要微信公眾號的appId和appsecret的,所以如果沒有這些,也是不能進行自定義的。

實現過程

  1. 首先可以先閱讀以下微信的JS-SDK的說明文件微信JS-SDK說明文件
  2. 繫結域名,登入微信公眾平臺,進入“公眾號設定”的功能設定裡面填寫js介面安全域名,這個是要填寫的是你微信瀏覽器要開啟的域名地址。不能新增IP地址。
  3. 引入js檔案
  4. 通過config介面注入許可權並驗證配置
  5. 這一步算是整個步驟中最關鍵的一步,必須正確的配置資訊才可以進行呼叫JS-SDK。
wx.config({
    debug: true, // 開啟除錯模式,呼叫的所有api的返回值會在客戶端alert出來,若要檢視傳入的引數,可以在pc端開啟,引數資訊會通過log打出,僅在pc端時才會列印。
    appId: '', // 必填,公眾號的唯一標識
    timestamp: , // 必填,生成簽名的時間戳
    nonceStr: '', // 必填,生成簽名的隨機串
    signature: '',// 必填,簽名
    jsApiList: [] // 必填,需要使用的JS介面列表
});

下面講如何獲取 timestamp, noceStr(記得這個駝峰結構),singature

獲取配置

先說說最煩人的singature,對於初學小程式的簡直要了老夫的命,這是啥玩意,還是簽名,所以我會把自己踩的坑給大家說一下。 獲取簽名實際是需要四步

1. 根據appId和appsecret獲取access_token;

2. 使用access_token獲取jsapi_ticket;

3. 使用時間戳,隨機數,jsapi_ticket和要訪問的url按照簽名演算法拼接字串;

4. 對第三步的字串進行SHA1加密,得到簽名;

第一步,獲取access_token

appId和appsecret可以在微信公眾平臺--開發-基本配置中查詢

public static String getAccess_token(String appId, String appSecret){

        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + appSecret;
        String accessToken = null;
        try
        {
            URL urlGet = new URL(url);
            HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();
            http.setRequestMethod("GET"); // 必須是get方式請求
            http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            http.setDoOutput(true);
            http.setDoInput(true);
            System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 連線超時30秒
            System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 讀取超時30秒
            http.connect();
            InputStream is = http.getInputStream();
            int size = is.available();
            byte[] jsonBytes = new byte[size];
            is.read(jsonBytes);
            String message = new String(jsonBytes, "UTF-8");
            JSONObject jsonObj = JSONObject.fromObject(message);
            accessToken = jsonObj.getString("access_token");
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return accessToken;
    }

第二步 獲取jsapi_ticket

/**
     * 獲得ACCESS_TICKET
     * 
     * @Title: ACCESS_TICKET
     * @Description: 獲得ACCESS_TICKET
     * @param @return 設定檔案
     * @return String 返回型別
     * @throws
     */
    public static String getAccess_ticket(String access_token) {  
        String ticket = null;  
        String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+ access_token +"&type=jsapi";//這個url連結和引數不能變  
        try {  
            URL urlGet = new URL(url);  
            HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();  
            http.setRequestMethod("GET"); // 必須是get方式請求  
            http.setRequestProperty("Content-Type","application/x-www-form-urlencoded");  
            http.setDoOutput(true);  
            http.setDoInput(true);  
            System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 連線超時30秒  
            System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 讀取超時30秒  
            http.connect();  
            InputStream is = http.getInputStream();  
            int size = is.available();  
            byte[] jsonBytes = new byte[size];  
            is.read(jsonBytes);  
            String message = new String(jsonBytes, "UTF-8");  
            JSONObject demoJson = JSONObject.fromObject(message);  
            System.out.println("JSON字串:"+demoJson);  
            ticket = demoJson.getString("ticket");  
            is.close();  
        } catch (Exception e) {  
                e.printStackTrace();  
        }  
        return ticket;  
    }  
    

這裡拿到對應的jsapi_ticket之後就可以進行引數排序和拼接字串並加密

第三步:SHA1加密

public static String SHA1(String decript) {  
        try {  
            MessageDigest digest = java.security.MessageDigest.getInstance("SHA-1");  
            digest.update(decript.getBytes());  
            byte messageDigest[] = digest.digest();  
            // Create Hex String  
            StringBuffer hexString = new StringBuffer();  
            // 位元組陣列轉換為 十六進位制 數  
                for (int i = 0; i < messageDigest.length; i++) {  
                    String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);  
                    if (shaHex.length() < 2) {  
                        hexString.append(0);  
                    }  
                    hexString.append(shaHex);  
                }  
                return hexString.toString();  
       
            } catch (NoSuchAlgorithmException e) {  
                e.printStackTrace();  
            }  
            return "";  
    }  

第四步: 獲取簽名

public static void main(String[] args) {  
    //1、獲取AccessToken  
    String accessToken = getAccessToken();  
      
    //2、獲取Ticket  
    String jsapi_ticket = getTicket(accessToken);  
      
    //3、時間戳和隨機字串  
    String noncestr = UUID.randomUUID().toString().replace("-", "").substring(0, 16);//隨機字串  
    String timestamp = String.valueOf(System.currentTimeMillis() / 1000);//時間戳  
      
    System.out.println("accessToken:"+accessToken+"\njsapi_ticket:"+jsapi_ticket+"\n時間戳:"+timestamp+"\n隨機字串:"+noncestr);  
      
    //4、獲取url  
    String url="http://www.luiyang.com/add.html";  
    /*根據JSSDK上面的規則進行計算,這裡比較簡單,我就手動寫啦 
    String[] ArrTmp = {"jsapi_ticket","timestamp","nonce","url"}; 
    Arrays.sort(ArrTmp); 
    StringBuffer sf = new StringBuffer(); 
    for(int i=0;i<ArrTmp.length;i++){ 
        sf.append(ArrTmp[i]); 
    } 
    */  
      
    //5、將引數排序並拼接字串  
    String str = "jsapi_ticket="+jsapi_ticket+"&noncestr="+noncestr+"&timestamp="+timestamp+"&url="+url;  
     
    //6、將字串進行sha1加密  
    String signature =SHA1(str);  
    System.out.println("引數:"+str+"\n簽名:"+signature);  
}  

改寫之後的程式碼,json格式返回。

protected void doPost(HttpServletRequest request, HttpServletResponse response){
        
        //appId和appSecret
        String appId = "XXXXX";
        String appSecret = "XXXXX";
        
        //外部傳入url獲取url url需要是微信中開啟的url否則會報錯。
        String URL = request.getParameter("url"); 
        //轉換url
        
        String url="";
        //需要轉換解碼url
        try {
            url = java.net.URLDecoder.decode(URL,"UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        //獲取access_token
        String aeecss_token = HttpUtil.getAccess_token(appId, appSecret);
        
        //獲取access_ticket
        String aeecss_ticket = HttpUtil.getAccess_ticket(aeecss_token);
        
        
         //3、時間戳和隨機字串  
        String nonceStr = UUID.randomUUID().toString().replace("-", "").substring(0, 16);//隨機字串  
        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);//時間戳  
          
        System.out.println("accessToken:"+aeecss_token+"\njsapi_ticket:"+aeecss_ticket+"\n時間戳:"+timestamp+"\n隨機字串:"+nonceStr);  
          
        
        //4、獲取url  
        //5、將引數排序並拼接字串  
        String str = "jsapi_ticket="+aeecss_ticket+"&noncestr="+nonceStr+"&timestamp="+timestamp+"&url="+url;  
         
        //6、將字串進行sha1加密  
        String signature =SHA1(str);  
        System.out.println("引數:"+str+"\n簽名:"+signature);  
        
        
        Map<String,String> map=new HashMap();
        map.put("appId",appId);
        map.put("timestamp",timestamp);
        map.put("accessToken",aeecss_token);
        map.put("ticket",aeecss_ticket);
        map.put("nonceStr",nonceStr);
        map.put("signature",signature);
        JSONObject jsonObject = JSONObject.fromObject(map);
        
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setContentType("application/json;charset=UTF-8");
        response.setCharacterEncoding("UTF-8");

        PrintWriter pw = null;
        try {
            pw = response.getWriter();
        } catch (IOException e1) {
            logger.error("**********reponse getWriter exception**********");
            e1.printStackTrace();
        }
        pw.write(jsonObject.toString());
        pw.close();
    }

這一段程式碼是改寫了,獲取簽名後把所有的資訊都返回json格式了。概要的都有了,這是就可以配置config了,此時應該是:

 $.ajax({
            url: 'http://10.25.74.68:8088',
            type: 'POST',
            dataType: 'json',
            //url需要編碼傳入而且要是完整的url除#之後的
            data: {"url":encodeURIComponent(window.location.href.split("#")[0])}
        })
        .done(function(res) {

            wx.config({
                debug: ture, //除錯階段建議開啟
                appId: res.appId,//APPID
                timestamp: res.timestamp,//上面main方法中拿到的時間戳timestamp
                nonceStr: res.nonceStr,//上面main方法中拿到的隨機數nonceStr
                signature: res.signature,//上面main方法中拿到的簽名signature
                //需要呼叫的方法介面
                jsApiList: [ 'onMenuShareTimeline','onMenuShareAppMessage','onMenuShareWeibo','onMenuShareQQ','onMenuShareQZone']
            });
   }

注意:

  1. url一定要是完整的url(當前網頁的URL,不包含#及其後面部分)最好是使用window.location.href.split("#")獲取得到,如果傳入固定的好像會報invalid signature錯誤,所以為了安全起見還是直接傳入當前的url
  2. 這個簽名的有效時間為7200秒,也就是2個小時,因此當超過兩個小時候,再訪問也會報invalid signature錯誤。但是這個我還沒有遇見,並不知道這麼解決,其他說是需要快取access_token和access_ticket
  3. 另外還有一個錯誤:invalid url domain 這個跟生成簽名時用的url有關係,官網的說法是: invalid url domain當前頁面所在域名與使用的appid沒有繫結,請確認正確填寫繫結的域名,如果使用了埠號,則配置的繫結域名也要加上埠號(一個appid可以繫結三個有效域名) 這個url必須是:“公眾號設定---功能設定----JS介面安全域名”中繫結的三個域名之一
  4. 如果以上配置都是正確,而且debug也設定為true了,在微信中訪問連線會出現config:ok的介面,就說明配置成功了
  5. 有時也可以把ajax請求放在setTimeout中進行請求。

自定義標題,內容和圖片

    wx.ready(function(){
                // alert("我已經進來了");
                wx.onMenuShareTimeline({
                    title: title, // 分享標題
                    link: window.location.href, // 分享連結,該連結域名或路徑必須與當前頁面對應的公眾號JS安全域名一致
                    imgUrl: "//upload-images.jianshu.io/upload_images/3429385-09282d70c0390d94.png?imageMogr2/auto-orient/strip|imageView2/1/w/300/h/240", // 分享圖示
                    success: function () {
                        // alert("成功")
                        // 使用者點選了分享後執行的回撥函式
                    }
                });
                wx.onMenuShareAppMessage({
                    title: title, // 分享標題
                    desc: descContent, // 分享描述
                    link: window.location.href, // 分享連結,該連結域名或路徑必須與當前頁面對應的公眾號JS安全域名一致
                    imgUrl: "//upload-images.jianshu.io/upload_images/3429385-09282d70c0390d94.png?imageMogr2/auto-orient/strip|imageView2/1/w/300/h/240", // 分享圖示
                    type: '', // 分享型別,music、video或link,不填預設為link
                    dataUrl: '', // 如果type是music或video,則要提供資料鏈接,預設為空
                    success: function () {
                        // alert("成功")
                        // 使用者點選了分享後執行的回撥函式
                    }
                });
                wx.onMenuShareQQ({
                    title: title, // 分享標題
                    desc: descContent, // 分享描述
                    link: window.location.href, // 分享連結
                    imgUrl: "//upload-images.jianshu.io/upload_images/3429385-09282d70c0390d94.png?imageMogr2/auto-orient/strip|imageView2/1/w/300/h/240", // 分享圖示
                    success: function () {
                        // alert("成功")
                        // 使用者確認分享後執行的回撥函式
                    },
                    cancel: function () {
                        // alert("失敗")
                        // 使用者取消分享後執行的回撥函式
                        // config資訊驗證失敗會執行error函式,如簽名過期導致驗證失敗,具體錯誤資訊可以開啟config的debug模式檢視,也可以在返回的res引數中檢視,對於SPA可以在這裡更新簽名。
                    }
                });
            });

注意:

  1. 應該把自定義的內容解除安裝wx.ready( // config資訊驗證後會執行ready方法,所有介面呼叫都必須在config介面獲得結果之後,config是一個客戶端的非同步操作,所以如果需要在頁面載入時就呼叫相關介面,則須把相關介面放在ready函式中呼叫來確保正確執行。對於使用者觸發時才呼叫的介面,則可以直接呼叫,不需要放在ready函式中。 )裡面,
  2. link該連結域名或路徑必須與當前頁面對應的公眾號JS安全域名
  3. imgUrl:最好是絕對地址的圖片,相對位置好像出不來 比如:'../assets/image/213.png'這樣是出不來的

作者:holy俊輝 連結:https://www.jianshu.com/p/bf743d52c6d3 來源:簡書 簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。