精华内容
下载资源
问答
  • H5分享到微信朋友圈与好友实现思路 本文只是实现思路,代码写的比较水,仅供参考 使用springBoot 返回ModelAndView 实现 HTML使用Thymeleaf 1.添加MyX509TrustManager类(从微信提供的包中导入或自己创建都可以) ...

    H5分享到微信朋友圈与好友实现思路

    本文只是实现思路,代码写的比较水,仅供参考

    使用springBoot 返回ModelAndView 实现

    HTML使用Thymeleaf

    1.添加MyX509TrustManager类(从微信提供的包中导入或自己创建都可以)

    import java.security.cert.CertificateException;  
    import java.security.cert.X509Certificate;  
      
    import javax.net.ssl.X509TrustManager;  
      
    public class MyX509TrustManager implements X509TrustManager {  
        public void checkClientTrusted(X509Certificate[] chain, String authType)  
                throws CertificateException  
              {  
              }  
      
              public void checkServerTrusted(X509Certificate[] chain, String authType)  
                throws CertificateException  
              {  
              }  
      
              public X509Certificate[] getAcceptedIssuers()  
              {  
                return null;  
              }  
    }  

    2.maven添加JSON依赖

    <dependency>
        <groupId>net.sf.json-lib</groupId>
        <artifactId>json-lib-ext-spring</artifactId>
        <version>1.0.2</version>
    </dependency>

    3.创建WeixinUtil类

    需要注意:

    1.由于微信限制access_token获取次数,access_token需要缓存,建议由程序统一获取和刷新access_token,其他业务逻辑所使用的access_token均来自于该统一获取的access_token,不应该各自去刷新,目前access_token的有效期为7200秒,此处示例代码不做处理,实际开发请自行处理

    2.微信appId与secret请根据项目要求自行存放到配置文件或Config类

    import java.io.BufferedReader;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.UnsupportedEncodingException;
    import java.net.ConnectException;
    import java.net.URL;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    import java.util.Formatter;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.UUID;
    
    import javax.net.ssl.HttpsURLConnection;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLSocketFactory;
    import javax.net.ssl.TrustManager;
    import javax.servlet.http.HttpServletRequest;
    
    import net.sf.json.JSONObject;
    
    public class WeixinUtil {
        
        /**
        * 方法名:httpRequest</br>
        * 详述:发送http请求</br>
        * @param requestUrl
        * @param requestMethod
        * @param outputStr
        * @return 说明返回值含义
        * @throws 说明发生此异常的条件
         */
        public static JSONObject httpRequest(String requestUrl,String requestMethod, String outputStr) {
            JSONObject jsonObject = null;
            StringBuffer buffer = new StringBuffer();
            try {
                TrustManager[] tm = { new MyX509TrustManager() };
                SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
                sslContext.init(null, tm, new java.security.SecureRandom());
                SSLSocketFactory ssf = sslContext.getSocketFactory();
                URL url = new URL(requestUrl);
                HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
                httpUrlConn.setSSLSocketFactory(ssf);
                httpUrlConn.setDoOutput(true);
                httpUrlConn.setDoInput(true);
                httpUrlConn.setUseCaches(false);
                httpUrlConn.setRequestMethod(requestMethod);
                if ("GET".equalsIgnoreCase(requestMethod))
                    httpUrlConn.connect();
                if (null != outputStr) {
                    OutputStream outputStream = httpUrlConn.getOutputStream();
                    outputStream.write(outputStr.getBytes("UTF-8"));
                    outputStream.close();
                }
                InputStream inputStream = httpUrlConn.getInputStream();
                InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
                BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
                String str = null;
                while ((str = bufferedReader.readLine()) != null) {
                    buffer.append(str);
                }
                bufferedReader.close();
                inputStreamReader.close();
                inputStream.close();
                inputStream = null;
                httpUrlConn.disconnect();
                jsonObject = JSONObject.fromObject(buffer.toString());
            } catch (ConnectException ce) {
                ce.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return jsonObject;
        }
    
        /**
        * 方法名:getWxConfig</br>
        * 详述:获取微信的配置信息 </br>
        * @param request
        * @return 说明返回值含义
        * @throws 说明发生此异常的条件
         */
        public static Map<String, Object> getWxConfig(HttpServletRequest request) {
            Map<String, Object> ret = new HashMap<String, Object>();
          
            //此处appid与secret应该放到配置文件中,测试实现仅供参考
            String appId = "wxappId "; // 必填,公众号的唯一标识
            String secret = "wxsecret";
    
            //url
            String requestUrl = request.getRequestURL().toString();
            
            String access_token = "";
            String jsapi_ticket = "";
            String timestamp = Long.toString(System.currentTimeMillis() / 1000); // 必填,生成签名的时间戳
            String nonceStr = UUID.randomUUID().toString(); // 必填,生成签名的随机串
            String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+ appId + "&secret=" + secret;
            JSONObject json = WeixinUtil.httpRequest(url, "GET", null);
            if (json != null) {
                //要注意,由于微信限制access_token获取次数,access_token需要缓存,
                //建议由程序统一获取和刷新access_token,其他业务逻辑所使用的access_token均来自于该统一获取的access_token,不应该各自去刷新,
                //目前access_token的有效期为7200秒,此处示例代码不做处理,实际开发请自行处理
                access_token = json.getString("access_token");
                url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+ access_token + "&type=jsapi";
                json = WeixinUtil.httpRequest(url, "GET", null);
                if (json != null) {
                    jsapi_ticket = json.getString("ticket");
                }
            }
            String signature = "";
            // 注意这里参数名必须全部小写,且必须有序
            String sign = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonceStr+ "&timestamp=" + timestamp + "&url=" + requestUrl;
            try {
                MessageDigest crypt = MessageDigest.getInstance("SHA-1");
                crypt.reset();
                crypt.update(sign.getBytes("UTF-8"));
                signature = byteToHex(crypt.digest());
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            ret.put("appId", appId);
            ret.put("timestamp", timestamp);
            ret.put("nonceStr", nonceStr);
            ret.put("signature", signature);
            return ret;
        }
    
        /**
        * 方法名:byteToHex</br>
        * 详述:字符串加密辅助方法 </br>
        * 开发人员:souvc  </br>
        * 创建时间:2016-1-5  </br>
        * @param hash
        * @return 说明返回值含义
        * @throws 说明发生此异常的条件
         */
        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;
        }
    }

    4.测试controller

    其中title/desc等字段亦可由前端通过js代入

    @Controller
    public class TestController {
    
        @RequestMapping(value = "/test", method = RequestMethod.GET)
        public ModelAndView test(HttpServletRequest request){
            ModelAndView model = new ModelAndView();
            Map<String,Object> ret = new HashMap<String,Object>();
            //获取必要参数信息
            ret= WeixinUtil.getWxConfig(request);
            根据业务编写业务代码
            //......
    
            //加入需要展示的标题title
            ret.put("title", "xxx");
            //加入需要展示的详情desc
            ret.put("desc", "xxx");
            //获取URL
            String url = request.getRequestURL().toString();
            //加入需要展示的详情URL
            ret.put("link", url);
            model.addObject("wxConfig",ret);
            //返回页面
            model.setViewName("test");
            return model;
        }
    }

    5.HTML页面

    //1.引入js
    <script src="http://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
    
    //2.通过config接口注入权限验证配置
    wx.config({
        debug: true,
        appId: '[(${wxConfig.appId})]',
        timestamp: '[(${wxConfig.timestamp})]',
        nonceStr: '[(${wxConfig.nonceStr})]',
        signature: '[(${wxConfig.signature})]',
        jsApiList: ['updateAppMessageShareData', 'updateTimelineShareData']
    });
    
    //3.通过ready接口处理成功验证,并调用相应接口
    wx.ready(function(){
        // 获取“分享到朋友圈”按钮点击状态及自定义分享内容接口
        wx.updateAppMessageShareData({
            title: '[(${wxConfig.title})]', // 分享标题
            desc: '[(${wxConfig.desc})]', // 分享描述
            link: '[(${wxConfig.link})]', //分享URL
            imgUrl: "https://picsum.photos/200/200", // 分享图标,此处我测试使用了外部图片
            success: function () {
                // 用户确认分享后执行的回调函数
            },
            cancel: function () {
                // 用户取消分享后执行的回调函数
            }
        });
        // 获取“分享给朋友”按钮点击状态及自定义分享内容接口
        wx.updateTimelineShareData({
            title: '[(${wxConfig.title})]', // 分享标题
            link: '[(${wxConfig.link})]', //分享URL
            //分享给朋友不需要使用分享描述desc字段
            imgUrl: "https://picsum.photos/200/200", // 分享图标,此处我测试使用了外部图片
            success: function () {
                // 用户确认分享后执行的回调函数
            },
            cancel: function () {
                // 用户取消分享后执行的回调函数
            }
        });
    });

    6.在微信公众号配置中添加JS接口安全域名

    7.测试效果

    分享给好友:

    分享到朋友圈:

    8.完成

    展开全文
  • h5 微信分享朋友和朋友圈

    千次阅读 2018-04-06 17:57:07
    转自:https://www.cnblogs.com/liangzia/p/7569443.htmlh5 微信分享朋友和朋友圈生成JS-SDK权限验证签名实现发送给朋友和分享到朋友圈时内容参数自定义 一、微信JS-SDK1. 获得Access Tokenaccess token的获得方法...

    转自:https://www.cnblogs.com/liangzia/p/7569443.html

    h5 微信分享朋友和朋友圈

    1. 生成JS-SDK权限验证签名
    2. 实现发送给朋友和分享到朋友圈时内容参数自定义

     

    一、微信JS-SDK

    1. 获得Access Token

    access token的获得方法在前面有介绍,详情见 微信公众平台开发(26) ACCESS TOKEN

    2. 获取jsapi_ticket

    生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket 。

    参考以下文档获取access_token(有效期7200秒,开发者必须在自己的服务全局缓存access_token):
    用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket),接口地址如下

    https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi

    成功返回如下JSON:

    复制代码
    复制代码
    {
        "errcode":0,
        "errmsg":"ok",
        "ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
        "expires_in":7200
    }
    复制代码
    复制代码

    获得jsapi_ticket之后,就可以生成JS-SDK权限验证的签名了。

    3. 签名算法实现

    签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。

    即signature=sha1(string1)。 示例:

    noncestr=Wm3WZYTPz0wzccnW
    jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg
    timestamp=1414587457
    url=http://mp.weixin.qq.com?params=value

    步骤1. 对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1:

    jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW&timestamp=1414587457&url=http://mp.weixin.qq.com?params=value

    步骤2. 对string1进行sha1签名,得到signature:

    0f9de62fce790f9a083d5c99e95740ceb90c27ed

    完整代码如下

    复制代码
    复制代码
    <?php
    class JSSDK {
      private $appId;
      private $appSecret;
    
      public function __construct($appId, $appSecret) {
        $this->appId = $appId;
        $this->appSecret = $appSecret;
      }
    
      public function getSignPackage() {
        $jsapiTicket = $this->getJsApiTicket();
    
        // 注意 URL 一定要动态获取,不能 hardcode.
        $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
        $url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
    
        $timestamp = time();
        $nonceStr = $this->createNonceStr();
    
        // 这里参数的顺序要按照 key 值 ASCII 码升序排序
        $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr&timestamp=$timestamp&url=$url";
    
        $signature = sha1($string);
    
        $signPackage = array(
          "appId"     => $this->appId,
          "nonceStr"  => $nonceStr,
          "timestamp" => $timestamp,
          "url"       => $url,
          "signature" => $signature,
          "rawString" => $string
        );
        return $signPackage; 
      }
    
      private function createNonceStr($length = 16) {
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
          $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
      }
    
      private function getJsApiTicket() {
        // jsapi_ticket 应该全局存储与更新,以下代码以写入到文件中做示例
        $data = json_decode(file_get_contents("jsapi_ticket.json"));
        if ($data->expire_time < time()) {
          $accessToken = $this->getAccessToken();
          // 如果是企业号用以下 URL 获取 ticket
          // $url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=$accessToken";
          $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=$accessToken";
          $res = json_decode($this->httpGet($url));
          $ticket = $res->ticket;
          if ($ticket) {
            $data->expire_time = time() + 7000;
            $data->jsapi_ticket = $ticket;
            $fp = fopen("jsapi_ticket.json", "w");
            fwrite($fp, json_encode($data));
            fclose($fp);
          }
        } else {
          $ticket = $data->jsapi_ticket;
        }
    
        return $ticket;
      }
    
      private function getAccessToken() {
        // access_token 应该全局存储与更新,以下代码以写入到文件中做示例
        $data = json_decode(file_get_contents("access_token.json"));
        if ($data->expire_time < time()) {
          // 如果是企业号用以下URL获取access_token
          // $url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=$this->appId&corpsecret=$this->appSecret";
          $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$this->appId&secret=$this->appSecret";
          $res = json_decode($this->httpGet($url));
          $access_token = $res->access_token;
          if ($access_token) {
            $data->expire_time = time() + 7000;
            $data->access_token = $access_token;
            $fp = fopen("access_token.json", "w");
            fwrite($fp, json_encode($data));
            fclose($fp);
          }
        } else {
          $access_token = $data->access_token;
        }
        return $access_token;
      }
    
      private function httpGet($url) {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_TIMEOUT, 500);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_URL, $url);
    
        $res = curl_exec($curl);
        curl_close($curl);
    
        return $res;
      }
    }
    复制代码
    复制代码

     

    二、发送给朋友和分享到朋友圈参数自定义

    1. 绑定域名

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

    2. 获取签名包

    <?php
    require_once "jssdk.php";
    $jssdk = new JSSDK("yourAppID", "yourAppSecret");
    $signPackage = $jssdk->GetSignPackage();
    ?>

    3. 引入JS文件

    在需要调用JS接口的页面引入如下JS文件,(支持https):

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

    4.通过config接口注入权限验证配置

    所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用。

    复制代码
    复制代码
    <script>
        wx.config({
            debug: false,
            appId: '<?php echo $signPackage["appId"];?>',
            timestamp: <?php echo $signPackage["timestamp"];?>,
            nonceStr: '<?php echo $signPackage["nonceStr"];?>',
            signature: '<?php echo $signPackage["signature"];?>',
            jsApiList: [
                // 所有要调用的 API 都要加到这个列表中
                'checkJsApi',
                'openLocation',
                'getLocation',
                'onMenuShareTimeline',
                'onMenuShareAppMessage'
              ]
        });
    </script>
    复制代码
    复制代码

    5. 通过ready接口处理成功验证

    地理位置需要在页面加载时就调用,需要把相关接口放在ready函数中调用来确保正确执行

    wx.ready(function () {
    });

    5.1 通过checkJsApi判断当前客户端版本是否支持分享参数自定义

    复制代码
    复制代码
            wx.checkJsApi({
                jsApiList: [
                    'getLocation',
                    'onMenuShareTimeline',
                    'onMenuShareAppMessage'
                ],
                success: function (res) {
                    alert(JSON.stringify(res));
                }
            });
    复制代码
    复制代码

    5.2 使用数组定义分享内容参数

    $news = array("Title" =>"微信公众平台开发实践", "Description"=>"本书共分10章,案例程序采用广泛流行的PHP、MySQL、XML、CSS、JavaScript、HTML5等程序语言及数据库实现。", "PicUrl" =>'https://images0.cnblogs.com/i/340216/201404/301756448922305.jpg', "Url" =>'http://www.cnblogs.com/txw1958/p/weixin-development-best-practice.html');    

    5.3. 实现JS分享功能

    复制代码
    复制代码
    wx.onMenuShareAppMessage({
              title: '<?php echo $news['Title'];?>',
              desc: '<?php echo $news['Description'];?>',
              link: '<?php echo $news['Url'];?>',
              imgUrl: '<?php echo $news['PicUrl'];?>',
              trigger: function (res) {
                // 不要尝试在trigger中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回
                // alert('用户点击发送给朋友');
              },
              success: function (res) {
                // alert('已分享');
              },
              cancel: function (res) {
                // alert('已取消');
              },
              fail: function (res) {
                // alert(JSON.stringify(res));
              }
            });
    
            wx.onMenuShareTimeline({
              title: '<?php echo $news['Title'];?>',
              link: '<?php echo $news['Url'];?>',
              imgUrl: '<?php echo $news['PicUrl'];?>',
              trigger: function (res) {
                // 不要尝试在trigger中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回
                // alert('用户点击分享到朋友圈');
              },
              success: function (res) {
                // alert('已分享');
              },
              cancel: function (res) {
                // alert('已取消');
              },
              fail: function (res) {
                // alert(JSON.stringify(res));
              }
            });
    复制代码
    复制代码

     

    三、实现效果

    弹出请求获取页面

    分享时的插件显示方倍工作室的 微信公众平台开发最佳实践

       


    展开全文
  • 移动端h5原生分享到朋友圈、微博等

    万次阅读 2018-08-19 23:18:57
    结合NativeShare和m-share两个包生成一个vue移动端的分享组件 shareBar.vue &amp;amp;amp;amp;lt;template&amp;amp;amp;amp;gt; &amp;amp;amp;amp;lt;div id=&amp;amp;amp;quot;...

    结合nativesharem-share两个包生成一个vue移动端的分享组件

    需要npm install NativeShare --savenpm install m-share --save

    这里写图片描述
    shareBar.vue

    <template>
      <div id="nativeShare">
        <div class="label">分享到</div>
        <div class="list">
          <span class="list-item" v-for="(button, index) in shareButtons" :key="index">
            <img :src="button.src" class="i" @click="call(button)">
            {{button.text}}
          </span>
        </div>
      </div>
    </template>
    
    <script>
    //https://github.com/fa-ge/NativeShare
    const nativeshare = () => import ('nativeshare') //这种引入方式nativeshare是Promise对象
    //https://github.com/backToNature/m-share
    const m_share = () => import ('m-share')
    var NativeShare, mShare
    export default {
      name: 'the-sharebar',
      data() {
        return {
          shareButtons:[
            {text: '微信好友', nativeshare:'wechatFriend', m_share: 'wx' , src: require('@/assets/weixin_friend.png')},
            {text: '朋友圈', nativeshare:'wechatTimeline', m_share: 'wxline', src: require('@/assets/weixin.png')},
            {text: '新浪微博', nativeshare:'weibo', m_share: 'sina', src: require('@/assets/weibo.png')},
            {text: 'QQ好友', nativeshare:'qqFriend', m_share: 'qq', src: require('@/assets/QQ.png')},
            {text: 'QQ空间', nativeshare:'qZone', m_share: 'qzone', src: require('@/assets/qqzone.png')},
            {text: '更多', nativeshare:'', m_share: '', src: require('@/assets/more.png')},
          ]
        }
      },
      computed: {
        config () {
          return {
            title: '分享标题',
            desc:'描述',
            img:'图片地址',
            img_title:'图片标题',
            link: '当前链接'
          }
        }
      },
      methods: {
        call(command) {
          let shareData = {  //nativeShare的参数模型
              title: this.config.title,
              desc: this.config.desc,
              // 如果是微信该link的域名必须要在微信后台配置的安全域名之内的。
              link: this.config.link,
              icon: this.config.url,
              // 不要过于依赖以下两个回调,很多浏览器是不支持的
              success: function() {
                  alert('success')
              },
              fail: function() {
                  alert('fail')
              }
          }
          let mShareData = {  //m-share的参数模型
                title: this.config.title, // 标题,默认读取document.title
                desc: this.config.desc, // 描述, 默认读取head标签:<meta name="description" content="desc" />
                link: this.config.link, // 网址,默认使用window.location.href
                imgUrl: this.config.img, // 图片, 默认取网页中第一个img标签
                fnDoShare(type) {
                    console.log('success')
                }
          }
          let nativeShare = new NativeShare()
          nativeShare.setShareData(shareData)
          try {
            nativeShare.call(command.nativeshare)
          } catch(e) {
            //iphone的qq浏览器调用此api
            //除iphone的qq浏览器外其他浏览器调用的api
            //在iphone的qq浏览器中比较奇葩,第一次调用nativeShare.call()会报错,第二次之后不报,这里是让每次调用nativeShare.call()之后都报错,然后统一去调m-share.to()方法
            mShare.to(command.m_share, mShareData)
          }
        }
      },
      mounted() {
        // ES6 标准
        nativeshare().then(res =>  {NativeShare = res.default} )
        // CommonJS 标准
        m_share().then(res => {mShare = res})
        //alert(browser)
      }
    }
    </script>
    
    <style scoped>
    #nativeShare {
        font-size: 13px;
    }
    
      .label {
          font-size: 18px;
      }
    
        .list-item {
            width: 30%;
            display: inline-block;
            text-align: center;
            margin: 10px 0;
        }
    
          .i {
              width: 40px;
              height: 40px;
              display: block;
              margin: 0 auto;
              margin-bottom: 5px;
              background-size: cover;
          }
    </style>
    
    

    config的参数也可以选择用组件间的通信传入、<the-sharebar :config="config" />

    注意

    现在已经发布npm包vue-native-share

    展开全文
  • 微信分享朋友分享朋友圈 1.准备工作 1.1.获取微信公众号的appid 和 密钥 1.2公众号设置中添加js安全域名,需要将文件放在默认的80端口下。可做映射,可更改tomcat配置 1.2.1端口映射 一 .添加映射将80端口映射...

    微信分享朋友分享朋友圈

    1.准备工作

    1.1.获取微信公众号的appid 和 密钥

    在这里插入图片描述

    1.2公众号设置中添加js安全域名,需要将文件放在默认的80端口下。可做映射,可更改tomcat配置

    1.2.1端口映射

    一 .添加映射将80端口映射到8080
    iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
    二. 删除映射(不需要时删除)
    查看映射编号  iptables -t nat -L -nv --line-numbers 
    删除项 “num” 对应的字母  iptables -t nat -D PREROUTING “num(实际上是对应的数字)”
    

    在这里插入图片描述

    2.后台操作

    2.1后台获取需要获取签名的url

    package com.weifeng.controller;
    
    import org.springframework.web.bind.annotation.CrossOrigin;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.util.Map;
    
    import static com.weifeng.utils.Duck.weixinSign;
    
    @RestController
    @CrossOrigin
    public class WechatController {
    
        //获取签名参数
        @GetMapping("weiSign")
        public Map<String, Object> weiSign( String url){
            System.out.println("url = " + url);
            //请求方法
            return weixinSign(url);
        }
    
    }
    
    

    获取签名需要先获取token 和 ticket

    package com.weifeng.utils;
    
    import com.alibaba.fastjson.JSONObject;
    import redis.clients.jedis.Jedis;
    
    import java.util.HashMap;
    import java.util.Map;
    
    
    public class Duck {
    
        public static Map<String, Object> weixinSign(String url1) {
            String json = "";
            String token = "";
            String ticket = "";
            Jedis jedis = new Jedis("127.0.0.1",6379);
            jedis.ping();
            Map<String,String> params = new HashMap<>();
            params.put("grant_type","client_credential");
            params.put("appid","你自己的appid");
            params.put("secret","你自己的密钥");
            if (jedis.exists("token")){
                token=jedis.get("token");
            }else {
                json = HttpClientUtil.doGet("https://api.weixin.qq.com/cgi-bin/token?",params);
                JSONObject jsonObject = JSONObject.parseObject(json);
                token=jsonObject.get("access_token").toString();
                System.out.println("token = " + token);
                jedis.setex("token",7200,token);
            }
            if (jedis.exists("weixinticket")){
                ticket = jedis.get("weixinticket");
            }else {
                String TUrl ="https://api.weixin.qq.com/cgi-bin/ticket/getticket?";
                HashMap<String, String> paramHashMap = new HashMap<>();
                paramHashMap.put("type","jsapi");
                paramHashMap.put("access_token",token);
                json = HttpClientUtil.doGet(TUrl,paramHashMap);
                System.out.println("json = " + json);
                JSONObject tickObject = JSONObject.parseObject(json);
                ticket=tickObject.get("ticket").toString();
                System.out.println(ticket);
                jedis.setex("weixinticket", 7200,ticket);
            }
            //调用获取签名方法
            Map<String, Object> sign = WeiXinSign.sign(ticket, url1);
            System.out.println("签名为"+sign);
            return sign;
        }
    }
    
    

    获取签名的方法返回签名相关所有的信息

    package com.weifeng.utils;
    
    import java.io.UnsupportedEncodingException;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    import java.util.*;
    
    public class WeiXinSign {
        public WeiXinSign() {
        }
    
        public static Map<String, Object> sign(String jsapi_ticket, String url) {
            System.out.println(url);
            Map<String, Object> ret = new HashMap();
            String nonce_str = create_nonce_str();//不带斜杠的uuid
            String timestamp = create_timestamp();//当前时间
            String signature = "";
            String jieguo = "";
            ArrayList<String> arr = new ArrayList();
            arr.add("jsapi_ticket=" + jsapi_ticket);
            arr.add("noncestr=" + nonce_str);
            arr.add("timestamp=" + timestamp);
            arr.add("url=" + url);
            Collections.sort(arr, new Comparator<String>() {
                @Override
                public int compare(String o1, String o2) {
                    try {
                        String str1 = new String(o1.toString().getBytes("GB2312"), "ISO-8859-1");
                        String str2 = new String(o2.toString().getBytes("GB2312"), "ISO-8859-1");
                        return str1.compareTo(str2);
                    } catch (UnsupportedEncodingException var4) {
                        var4.printStackTrace();
                        return 0;
                    }
                }
            });
    
            for(int i = 0; i < arr.size(); ++i) {
                if (i < arr.size() - 1) {
                    jieguo = jieguo + (String)arr.get(i) + "&";
                }
    
                if (i == arr.size() - 1) {
                    jieguo = jieguo + (String)arr.get(i);
                }
            }
    
            try {
                MessageDigest crypt = MessageDigest.getInstance("SHA-1");
                crypt.reset();
                System.out.println("jieguo = " + jieguo);
                crypt.update(jieguo.getBytes("UTF-8"));
                signature = byteToHex(crypt.digest());
            } catch (NoSuchAlgorithmException var9) {
                var9.printStackTrace();
            } catch (UnsupportedEncodingException var10) {
                var10.printStackTrace();
            }
    
            ret.put("url", url);
            ret.put("jsapi_ticket", jsapi_ticket);
            ret.put("nonceStr", nonce_str);
            ret.put("timestamp", Long.parseLong(timestamp));
            ret.put("signature", signature);
            return ret;
        }
    
        private static String byteToHex(final byte[] hash) {
            Formatter formatter = new Formatter();
            byte[] var2 = hash;
            int var3 = hash.length;
    
            for(int var4 = 0; var4 < var3; ++var4) {
                byte b = var2[var4];
                formatter.format("%02x", b);
            }
    
            String result = formatter.toString();
            formatter.close();
            return result;
        }
    
        private static String create_nonce_str() {
            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
            return uuid;
        }
    
        private static String create_timestamp() {
            return Long.toString(System.currentTimeMillis() / 1000L);
        }
    }
    

    3.前端操作

    3.1获取官方的js模板

    !
    function(e, n) {
        "function" == typeof define && (define.amd || define.cmd) ? define(function() {
            return n(e)
        }) : n(e, !0)
    } (this,
    function(e, n) {
        function i(n, i, t) {
            e.WeixinJSBridge ? WeixinJSBridge.invoke(n, o(i),
            function(e) {
                c(n, e, t)
            }) : u(n, t)
        }
        function t(n, i, t) {
            e.WeixinJSBridge ? WeixinJSBridge.on(n,
            function(e) {
                t && t.trigger && t.trigger(e),
                c(n, e, i)
            }) : t ? u(n, t) : u(n, i)
        }
        function o(e) {
            return e = e || {},
            e.appId = C.appId,
            e.verifyAppId = C.appId,
            e.verifySignType = "sha1",
            e.verifyTimestamp = C.timestamp + "",
            e.verifyNonceStr = C.nonceStr,
            e.verifySignature = C.signature,
            e
        }
        function r(e) {
            return {
                timeStamp: e.timestamp + "",
                nonceStr: e.nonceStr,
                package: e.package,
                paySign: e.paySign,
                signType: e.signType || "SHA1"
            }
        }
        function a(e) {
            return e.postalCode = e.addressPostalCode,
            delete e.addressPostalCode,
            e.provinceName = e.proviceFirstStageName,
            delete e.proviceFirstStageName,
            e.cityName = e.addressCitySecondStageName,
            delete e.addressCitySecondStageName,
            e.countryName = e.addressCountiesThirdStageName,
            delete e.addressCountiesThirdStageName,
            e.detailInfo = e.addressDetailInfo,
            delete e.addressDetailInfo,
            e
        }
        function c(e, n, i) {
            "openEnterpriseChat" == e && (n.errCode = n.err_code),
            delete n.err_code,
            delete n.err_desc,
            delete n.err_detail;
            var t = n.errMsg;
            t || (t = n.err_msg, delete n.err_msg, t = s(e, t), n.errMsg = t),
            (i = i || {})._complete && (i._complete(n), delete i._complete),
            t = n.errMsg || "",
            C.debug && !i.isInnerInvoke && alert(JSON.stringify(n));
            var o = t.indexOf(":");
            switch (t.substring(o + 1)) {
            case "ok":
                i.success && i.success(n);
                break;
            case "cancel":
                i.cancel && i.cancel(n);
                break;
            default:
                i.fail && i.fail(n)
            }
            i.complete && i.complete(n)
        }
        function s(e, n) {
            var i = e,
            t = v[i];
            t && (i = t);
            var o = "ok";
            if (n) {
                var r = n.indexOf(":");
                "confirm" == (o = n.substring(r + 1)) && (o = "ok"),
                "failed" == o && (o = "fail"),
                -1 != o.indexOf("failed_") && (o = o.substring(7)),
                -1 != o.indexOf("fail_") && (o = o.substring(5)),
                "access denied" != (o = (o = o.replace(/_/g, " ")).toLowerCase()) && "no permission to execute" != o || (o = "permission denied"),
                "config" == i && "function not exist" == o && (o = "ok"),
                "" == o && (o = "fail")
            }
            return n = i + ":" + o
        }
        function d(e) {
            if (e) {
                for (var n = 0,
                i = e.length; n < i; ++n) {
                    var t = e[n],
                    o = h[t];
                    o && (e[n] = o)
                }
                return e
            }
        }
        function u(e, n) {
            if (! (!C.debug || n && n.isInnerInvoke)) {
                var i = v[e];
                i && (e = i),
                n && n._complete && delete n._complete,
                console.log('"' + e + '",', n || "")
            }
        }
        function l(e) {
            if (! (k || w || C.debug || x < "6.0.2" || V.systemType < 0)) {
                var n = new Image;
                V.appId = C.appId,
                V.initTime = A.initEndTime - A.initStartTime,
                V.preVerifyTime = A.preVerifyEndTime - A.preVerifyStartTime,
                N.getNetworkType({
                    isInnerInvoke: !0,
                    success: function(e) {
                        V.networkType = e.networkType;
                        var i = "https://open.weixin.qq.com/sdk/report?v=" + V.version + "&o=" + V.isPreVerifyOk + "&s=" + V.systemType + "&c=" + V.clientVersion + "&a=" + V.appId + "&n=" + V.networkType + "&i=" + V.initTime + "&p=" + V.preVerifyTime + "&u=" + V.url;
                        n.src = i
                    }
                })
            }
        }
        function p() {
            return (new Date).getTime()
        }
        function f(n) {
            T && (e.WeixinJSBridge ? n() : S.addEventListener && S.addEventListener("WeixinJSBridgeReady", n, !1))
        }
        function m() {
            N.invoke || (N.invoke = function(n, i, t) {
                e.WeixinJSBridge && WeixinJSBridge.invoke(n, o(i), t)
            },
            N.on = function(n, i) {
                e.WeixinJSBridge && WeixinJSBridge.on(n, i)
            })
        }
        function g(e) {
            if ("string" == typeof e && e.length > 0) {
                var n = e.split("?")[0],
                i = e.split("?")[1];
                return n += ".html",
                void 0 !== i ? n + "?" + i: n
            }
        }
        if (!e.jWeixin) {
            var h = {
                config: "preVerifyJSAPI",
                onMenuShareTimeline: "menu:share:timeline",
                onMenuShareAppMessage: "menu:share:appmessage",
                onMenuShareQQ: "menu:share:qq",
                onMenuShareWeibo: "menu:share:weiboApp",
                onMenuShareQZone: "menu:share:QZone",
                previewImage: "imagePreview",
                getLocation: "geoLocation",
                openProductSpecificView: "openProductViewWithPid",
                addCard: "batchAddCard",
                openCard: "batchViewCard",
                chooseWXPay: "getBrandWCPayRequest",
                openEnterpriseRedPacket: "getRecevieBizHongBaoRequest",
                startSearchBeacons: "startMonitoringBeacons",
                stopSearchBeacons: "stopMonitoringBeacons",
                onSearchBeacons: "onBeaconsInRange",
                consumeAndShareCard: "consumedShareCard",
                openAddress: "editAddress"
            },
            v = function() {
                var e = {};
                for (var n in h) e[h[n]] = n;
                return e
            } (),
            S = e.document,
            I = S.title,
            y = navigator.userAgent.toLowerCase(),
            _ = navigator.platform.toLowerCase(),
            k = !(!_.match("mac") && !_.match("win")),
            w = -1 != y.indexOf("wxdebugger"),
            T = -1 != y.indexOf("micromessenger"),
            M = -1 != y.indexOf("android"),
            P = -1 != y.indexOf("iphone") || -1 != y.indexOf("ipad"),
            x = function() {
                var e = y.match(/micromessenger\/(\d+\.\d+\.\d+)/) || y.match(/micromessenger\/(\d+\.\d+)/);
                return e ? e[1] : ""
            } (),
            A = {
                initStartTime: p(),
                initEndTime: 0,
                preVerifyStartTime: 0,
                preVerifyEndTime: 0
            },
            V = {
                version: 1,
                appId: "",
                initTime: 0,
                preVerifyTime: 0,
                networkType: "",
                isPreVerifyOk: 1,
                systemType: P ? 1 : M ? 2 : -1,
                clientVersion: x,
                url: encodeURIComponent(location.href)
            },
            C = {},
            L = {
                _completes: []
            },
            B = {
                state: 0,
                data: {}
            };
            f(function() {
                A.initEndTime = p()
            });
            var O = !1,
            E = [],
            N = {
                config: function(e) {
                    C = e,
                    u("config", e);
                    var n = !1 !== C.check;
                    f(function() {
                        if (n) i(h.config, {
                            verifyJsApiList: d(C.jsApiList)
                        },
                        function() {
                            L._complete = function(e) {
                                A.preVerifyEndTime = p(),
                                B.state = 1,
                                B.data = e
                            },
                            L.success = function(e) {
                                V.isPreVerifyOk = 0
                            },
                            L.fail = function(e) {
                                L._fail ? L._fail(e) : B.state = -1
                            };
                            var e = L._completes;
                            return e.push(function() {
                                l()
                            }),
                            L.complete = function(n) {
                                for (var i = 0,
                                t = e.length; i < t; ++i) e[i]();
                                L._completes = []
                            },
                            L
                        } ()),
                        A.preVerifyStartTime = p();
                        else {
                            B.state = 1;
                            for (var e = L._completes,
                            t = 0,
                            o = e.length; t < o; ++t) e[t]();
                            L._completes = []
                        }
                    }),
                    m()
                },
                ready: function(e) {
                    0 != B.state ? e() : (L._completes.push(e), !T && C.debug && e())
                },
                error: function(e) {
                    x < "6.0.2" || ( - 1 == B.state ? e(B.data) : L._fail = e)
                },
                checkJsApi: function(e) {
                    var n = function(e) {
                        var n = e.checkResult;
                        for (var i in n) {
                            var t = v[i];
                            t && (n[t] = n[i], delete n[i])
                        }
                        return e
                    };
                    i("checkJsApi", {
                        jsApiList: d(e.jsApiList)
                    },
                    (e._complete = function(e) {
                        if (M) {
                            var i = e.checkResult;
                            i && (e.checkResult = JSON.parse(i))
                        }
                        e = n(e)
                    },
                    e))
                },
                onMenuShareTimeline: function(e) {
                    t(h.onMenuShareTimeline, {
                        complete: function() {
                            i("shareTimeline", {
                                title: e.title || I,
                                desc: e.title || I,
                                img_url: e.imgUrl || "",
                                link: e.link || location.href,
                                type: e.type || "link",
                                data_url: e.dataUrl || ""
                            },
                            e)
                        }
                    },
                    e)
                },
                onMenuShareAppMessage: function(e) {
                    t(h.onMenuShareAppMessage, {
                        complete: function(n) {
                            "favorite" === n.scene ? i("sendAppMessage", {
                                title: e.title || I,
                                desc: e.desc || "",
                                link: e.link || location.href,
                                img_url: e.imgUrl || "",
                                type: e.type || "link",
                                data_url: e.dataUrl || ""
                            }) : i("sendAppMessage", {
                                title: e.title || I,
                                desc: e.desc || "",
                                link: e.link || location.href,
                                img_url: e.imgUrl || "",
                                type: e.type || "link",
                                data_url: e.dataUrl || ""
                            },
                            e)
                        }
                    },
                    e)
                },
                onMenuShareQQ: function(e) {
                    t(h.onMenuShareQQ, {
                        complete: function() {
                            i("shareQQ", {
                                title: e.title || I,
                                desc: e.desc || "",
                                img_url: e.imgUrl || "",
                                link: e.link || location.href
                            },
                            e)
                        }
                    },
                    e)
                },
                onMenuShareWeibo: function(e) {
                    t(h.onMenuShareWeibo, {
                        complete: function() {
                            i("shareWeiboApp", {
                                title: e.title || I,
                                desc: e.desc || "",
                                img_url: e.imgUrl || "",
                                link: e.link || location.href
                            },
                            e)
                        }
                    },
                    e)
                },
                onMenuShareQZone: function(e) {
                    t(h.onMenuShareQZone, {
                        complete: function() {
                            i("shareQZone", {
                                title: e.title || I,
                                desc: e.desc || "",
                                img_url: e.imgUrl || "",
                                link: e.link || location.href
                            },
                            e)
                        }
                    },
                    e)
                },
                updateTimelineShareData: function(e) {
                    i("updateTimelineShareData", {
                        title: e.title,
                        link: e.link,
                        imgUrl: e.imgUrl
                    },
                    e)
                },
                updateAppMessageShareData: function(e) {
                    i("updateAppMessageShareData", {
                        title: e.title,
                        desc: e.desc,
                        link: e.link,
                        imgUrl: e.imgUrl
                    },
                    e)
                },
                startRecord: function(e) {
                    i("startRecord", {},
                    e)
                },
                stopRecord: function(e) {
                    i("stopRecord", {},
                    e)
                },
                onVoiceRecordEnd: function(e) {
                    t("onVoiceRecordEnd", e)
                },
                playVoice: function(e) {
                    i("playVoice", {
                        localId: e.localId
                    },
                    e)
                },
                pauseVoice: function(e) {
                    i("pauseVoice", {
                        localId: e.localId
                    },
                    e)
                },
                stopVoice: function(e) {
                    i("stopVoice", {
                        localId: e.localId
                    },
                    e)
                },
                onVoicePlayEnd: function(e) {
                    t("onVoicePlayEnd", e)
                },
                uploadVoice: function(e) {
                    i("uploadVoice", {
                        localId: e.localId,
                        isShowProgressTips: 0 == e.isShowProgressTips ? 0 : 1
                    },
                    e)
                },
                downloadVoice: function(e) {
                    i("downloadVoice", {
                        serverId: e.serverId,
                        isShowProgressTips: 0 == e.isShowProgressTips ? 0 : 1
                    },
                    e)
                },
                translateVoice: function(e) {
                    i("translateVoice", {
                        localId: e.localId,
                        isShowProgressTips: 0 == e.isShowProgressTips ? 0 : 1
                    },
                    e)
                },
                chooseImage: function(e) {
                    i("chooseImage", {
                        scene: "1|2",
                        count: e.count || 9,
                        sizeType: e.sizeType || ["original", "compressed"],
                        sourceType: e.sourceType || ["album", "camera"]
                    },
                    (e._complete = function(e) {
                        if (M) {
                            var n = e.localIds;
                            try {
                                n && (e.localIds = JSON.parse(n))
                            } catch(e) {}
                        }
                    },
                    e))
                },
                getLocation: function(e) {},
                previewImage: function(e) {
                    i(h.previewImage, {
                        current: e.current,
                        urls: e.urls
                    },
                    e)
                },
                uploadImage: function(e) {
                    i("uploadImage", {
                        localId: e.localId,
                        isShowProgressTips: 0 == e.isShowProgressTips ? 0 : 1
                    },
                    e)
                },
                downloadImage: function(e) {
                    i("downloadImage", {
                        serverId: e.serverId,
                        isShowProgressTips: 0 == e.isShowProgressTips ? 0 : 1
                    },
                    e)
                },
                getLocalImgData: function(e) { ! 1 === O ? (O = !0, i("getLocalImgData", {
                        localId: e.localId
                    },
                    (e._complete = function(e) {
                        if (O = !1, E.length > 0) {
                            var n = E.shift();
                            wx.getLocalImgData(n)
                        }
                    },
                    e))) : E.push(e)
                },
                getNetworkType: function(e) {
                    var n = function(e) {
                        var n = e.errMsg;
                        e.errMsg = "getNetworkType:ok";
                        var i = e.subtype;
                        if (delete e.subtype, i) e.networkType = i;
                        else {
                            var t = n.indexOf(":"),
                            o = n.substring(t + 1);
                            switch (o) {
                            case "wifi":
                            case "edge":
                            case "wwan":
                                e.networkType = o;
                                break;
                            default:
                                e.errMsg = "getNetworkType:fail"
                            }
                        }
                        return e
                    };
                    i("getNetworkType", {},
                    (e._complete = function(e) {
                        e = n(e)
                    },
                    e))
                },
                openLocation: function(e) {
                    i("openLocation", {
                        latitude: e.latitude,
                        longitude: e.longitude,
                        name: e.name || "",
                        address: e.address || "",
                        scale: e.scale || 28,
                        infoUrl: e.infoUrl || ""
                    },
                    e)
                },
                getLocation: function(e) {
                    e = e || {},
                    i(h.getLocation, {
                        type: e.type || "wgs84"
                    },
                    (e._complete = function(e) {
                        delete e.type
                    },
                    e))
                },
                hideOptionMenu: function(e) {
                    i("hideOptionMenu", {},
                    e)
                },
                showOptionMenu: function(e) {
                    i("showOptionMenu", {},
                    e)
                },
                closeWindow: function(e) {
                    i("closeWindow", {},
                    e = e || {})
                },
                hideMenuItems: function(e) {
                    i("hideMenuItems", {
                        menuList: e.menuList
                    },
                    e)
                },
                showMenuItems: function(e) {
                    i("showMenuItems", {
                        menuList: e.menuList
                    },
                    e)
                },
                hideAllNonBaseMenuItem: function(e) {
                    i("hideAllNonBaseMenuItem", {},
                    e)
                },
                showAllNonBaseMenuItem: function(e) {
                    i("showAllNonBaseMenuItem", {},
                    e)
                },
                scanQRCode: function(e) {
                    i("scanQRCode", {
                        needResult: (e = e || {}).needResult || 0,
                        scanType: e.scanType || ["qrCode", "barCode"]
                    },
                    (e._complete = function(e) {
                        if (P) {
                            var n = e.resultStr;
                            if (n) {
                                var i = JSON.parse(n);
                                e.resultStr = i && i.scan_code && i.scan_code.scan_result
                            }
                        }
                    },
                    e))
                },
                openAddress: function(e) {
                    i(h.openAddress, {},
                    (e._complete = function(e) {
                        e = a(e)
                    },
                    e))
                },
                openProductSpecificView: function(e) {
                    i(h.openProductSpecificView, {
                        pid: e.productId,
                        view_type: e.viewType || 0,
                        ext_info: e.extInfo
                    },
                    e)
                },
                addCard: function(e) {
                    for (var n = e.cardList,
                    t = [], o = 0, r = n.length; o < r; ++o) {
                        var a = n[o],
                        c = {
                            card_id: a.cardId,
                            card_ext: a.cardExt
                        };
                        t.push(c)
                    }
                    i(h.addCard, {
                        card_list: t
                    },
                    (e._complete = function(e) {
                        var n = e.card_list;
                        if (n) {
                            for (var i = 0,
                            t = (n = JSON.parse(n)).length; i < t; ++i) {
                                var o = n[i];
                                o.cardId = o.card_id,
                                o.cardExt = o.card_ext,
                                o.isSuccess = !!o.is_succ,
                                delete o.card_id,
                                delete o.card_ext,
                                delete o.is_succ
                            }
                            e.cardList = n,
                            delete e.card_list
                        }
                    },
                    e))
                },
                chooseCard: function(e) {
                    i("chooseCard", {
                        app_id: C.appId,
                        location_id: e.shopId || "",
                        sign_type: e.signType || "SHA1",
                        card_id: e.cardId || "",
                        card_type: e.cardType || "",
                        card_sign: e.cardSign,
                        time_stamp: e.timestamp + "",
                        nonce_str: e.nonceStr
                    },
                    (e._complete = function(e) {
                        e.cardList = e.choose_card_info,
                        delete e.choose_card_info
                    },
                    e))
                },
                openCard: function(e) {
                    for (var n = e.cardList,
                    t = [], o = 0, r = n.length; o < r; ++o) {
                        var a = n[o],
                        c = {
                            card_id: a.cardId,
                            code: a.code
                        };
                        t.push(c)
                    }
                    i(h.openCard, {
                        card_list: t
                    },
                    e)
                },
                consumeAndShareCard: function(e) {
                    i(h.consumeAndShareCard, {
                        consumedCardId: e.cardId,
                        consumedCode: e.code
                    },
                    e)
                },
                chooseWXPay: function(e) {
                    i(h.chooseWXPay, r(e), e)
                },
                openEnterpriseRedPacket: function(e) {
                    i(h.openEnterpriseRedPacket, r(e), e)
                },
                startSearchBeacons: function(e) {
                    i(h.startSearchBeacons, {
                        ticket: e.ticket
                    },
                    e)
                },
                stopSearchBeacons: function(e) {
                    i(h.stopSearchBeacons, {},
                    e)
                },
                onSearchBeacons: function(e) {
                    t(h.onSearchBeacons, e)
                },
                openEnterpriseChat: function(e) {
                    i("openEnterpriseChat", {
                        useridlist: e.userIds,
                        chatname: e.groupName
                    },
                    e)
                },
                launchMiniProgram: function(e) {
                    i("launchMiniProgram", {
                        targetAppId: e.targetAppId,
                        path: g(e.path),
                        envVersion: e.envVersion
                    },
                    e)
                },
                miniProgram: {
                    navigateBack: function(e) {
                        e = e || {},
                        f(function() {
                            i("invokeMiniProgramAPI", {
                                name: "navigateBack",
                                arg: {
                                    delta: e.delta || 1
                                }
                            },
                            e)
                        })
                    },
                    navigateTo: function(e) {
                        f(function() {
                            i("invokeMiniProgramAPI", {
                                name: "navigateTo",
                                arg: {
                                    url: e.url
                                }
                            },
                            e)
                        })
                    },
                    redirectTo: function(e) {
                        f(function() {
                            i("invokeMiniProgramAPI", {
                                name: "redirectTo",
                                arg: {
                                    url: e.url
                                }
                            },
                            e)
                        })
                    },
                    switchTab: function(e) {
                        f(function() {
                            i("invokeMiniProgramAPI", {
                                name: "switchTab",
                                arg: {
                                    url: e.url
                                }
                            },
                            e)
                        })
                    },
                    reLaunch: function(e) {
                        f(function() {
                            i("invokeMiniProgramAPI", {
                                name: "reLaunch",
                                arg: {
                                    url: e.url
                                }
                            },
                            e)
                        })
                    },
                    postMessage: function(e) {
                        f(function() {
                            i("invokeMiniProgramAPI", {
                                name: "postMessage",
                                arg: e.data || {}
                            },
                            e)
                        })
                    },
                    getEnv: function(n) {
                        f(function() {
                            n({
                                miniprogram: "miniprogram" === e.__wxjs_environment
                            })
                        })
                    }
                }
            },
            b = 1,
            R = {};
            return S.addEventListener("error",
            function(e) {
                if (!M) {
                    var n = e.target,
                    i = n.tagName,
                    t = n.src;
                    if (("IMG" == i || "VIDEO" == i || "AUDIO" == i || "SOURCE" == i) && -1 != t.indexOf("wxlocalresource://")) {
                        e.preventDefault(),
                        e.stopPropagation();
                        var o = n["wx-id"];
                        if (o || (o = b++, n["wx-id"] = o), R[o]) return;
                        R[o] = !0,
                        wx.ready(function() {
                            wx.getLocalImgData({
                                localId: t,
                                success: function(e) {
                                    n.src = e.localData
                                }
                            })
                        })
                    }
                }
            },
            !0),
            S.addEventListener("load",
            function(e) {
                if (!M) {
                    var n = e.target,
                    i = n.tagName;
                    n.src;
                    if ("IMG" == i || "VIDEO" == i || "AUDIO" == i || "SOURCE" == i) {
                        var t = n["wx-id"];
                        t && (R[t] = !1)
                    }
                }
            },
            !0),
            n && (e.wx = e.jWeixin = N),
            N
        }
    });
    

    编写html代码

    <!DOCTYPE html>
    <html>
    
    <head>
    	<meta charset="utf-8" />
    	<meta name="viewport" content="width=device-width, initial-scale=1">
    	<title></title>
    	<button class="btn btn_primary" id="onMenuShareAppMessage">onMenuShareAppMessage</button>
    </head>
    
    <body>
    
    </body>
    <script src="http://apps.bdimg.com/libs/jquery/1.9.1/jquery.min.js"></script>
    <script type="text/javascript" src="jweixin-1.0.0.js"></script>
    <script type="text/javascript">
    	$(function() {
    	
        //对url进行编码
    
        var localUrl = encodeURIComponent(location.href.split('#')[0]);
        //url传到后台格式
        // var Url =localUrl;
    	alert(localUrl);
        //这几个参数都是后台从微信公众平台获取到的
        var nonceStr, signature, timestamp, appId, shareUrl;
        $.ajax({
            //后台获取参数接口
           // url: "http://ym1.jiang178.com:8089/send/app/message/weiSign?url" + localUrl,
    	     url: "http://ym1.jiang178.com/weiSign?url=" + localUrl,
            // beforeSend: function(xhr) {
            //     xhr.setRequestHeader("Token", getCookie("token"));
            // },
            type: 'get',
            success: function(data) {
                //得到参数
    		    appId = "wx5e0c69abe17926d8";
    		    timestamp = data.timestamp;
    		    signature = data.signature;
    		    nonceStr = data.nonceStr;
    		    shareUrl = "http://ym1.jiang178.com/share.html";
    			
    			wx.config({
    				debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
    				appId: appId, // 必填,企业号的唯一标识,此处填写企业号corpid
    				timestamp: timestamp, // 必填,生成签名的时间戳
    				nonceStr: nonceStr, // 必填,生成签名的随机串
    				signature: signature,// 必填,签名,见附录1
    				jsApiList: [
    					'updateTimelineShareData',
    					'updateAppMessageShareData'
    				]
    			});
    			wx.ready(function () {      //需在用户可能点击分享按钮前就先调用
    				wx.updateTimelineShareData({
    					title: "eeeeeee",// 分享标题
    					desc: "eeeeeee", // 分享描述
    					link: shareUrl, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
    					imgUrl: "http://jlpa.jiang178.com/home/ubuntu/JLProd/upload/image/20191029/1572311071647000597.png", // 分享图标
    					success: function () {
    						// alert("分享成功");
    					}
    				})
    			});
    
    			//自定义“分享给朋友”及“分享到QQ”按钮的分享内容(1.4.0)
    			wx.ready(function () {   //需在用户可能点击分享按钮前就先调用
    				wx.updateAppMessageShareData({
    					title: "eeeeeee", // 分享标题
    					desc: "eeeeeee", // 分享描述
    					link: shareUrl, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
    					imgUrl: "http://jlpa.jiang178.com/home/ubuntu/JLProd/upload/image/20191029/1572311071647000597.png", // 分享图标
    					success: function () {
    						// alert("分享成功");
    					}
    				})
    			});	
    		}
        });
    	
    
            
    
    })
    </script>
    
    </html>
    
    

    4.服务器及后台配置

    在这里插入图片描述

    TIP:**返回签名接口,html文件,js安全约束文件在同一个包下

    需要对返回签名接口配置转发,转发路径为服务器路径

    4.1代码配置转发

    在这里插入图片描述

    package com.weifeng.filter;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.CorsRegistry;
    import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
    
    
    @Configuration
    public class CorsConfig extends WebMvcConfigurerAdapter {
    
        @Override
    
        public void addCorsMappings(CorsRegistry registry) {
    
            registry.addMapping("/**")
    
                    .allowedOriginPatterns("*")
    
                    .allowCredentials(true)
    
                    .allowedMethods("GET", "POST", "DELETE", "PUT")
    
                    .maxAge(3600);
        }
    
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/**").addResourceLocations("file:/home/zhouziwei/share/");
    
        }
    }
    

    请求get ,post 方法的工具类

    package com.weifeng.utils;
    
    import com.alibaba.fastjson.JSONObject;
    import org.apache.http.HttpEntity;
    import org.apache.http.NameValuePair;
    import org.apache.http.ParseException;
    import org.apache.http.client.entity.UrlEncodedFormEntity;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.client.utils.URIBuilder;
    import org.apache.http.entity.ContentType;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.message.BasicHeader;
    import org.apache.http.message.BasicNameValuePair;
    import org.apache.http.protocol.HTTP;
    import org.apache.http.util.EntityUtils;
    
    import java.io.IOException;
    import java.net.URI;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    
    public class HttpClientUtil {
        /**
         *  描述:发送get请求
         * @param url 请求URL
         * @param param 请求参数 key:value url携带参数 或者无参可不填
         * @author zhouziwei
         * @date 2021/3/10 17:56
         */
        public static String doGet(String url, Map<String, String> param) {
    
            // 创建Httpclient对象
            CloseableHttpClient httpclient = HttpClients.createDefault();
    
            String resultString = "";
            CloseableHttpResponse response = null;
            try {
                // 创建uri
                URIBuilder builder = new URIBuilder(url);
                if (param != null) {
                    for (String key : param.keySet()) {
                        builder.addParameter(key, param.get(key));
                    }
                }
                URI uri = builder.build();
    
                // 创建http GET请求
                HttpGet httpGet = new HttpGet(uri);
    
                // 执行请求
                response = httpclient.execute(httpGet);
                // 判断返回状态是否为200
                if (response.getStatusLine().getStatusCode() == 200) {
                    resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (response != null) {
                        response.close();
                    }
                    httpclient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return resultString;
        }
    
        public static String doGet(String url) {
            return doGet(url, null);
        }
    
        /**
         *  描述:发送post请求
         *
         * @author zhouziwei
         * @date 2021/3/19 15:01
         */
        public static String send(String url, JSONObject jsonObject, String encoding) throws ParseException, IOException{
            String body = "";
    
            //创建httpclient对象
            CloseableHttpClient client = HttpClients.createDefault();
            //创建post方式请求对象
            HttpPost httpPost = new HttpPost(url);
    
            //装填参数
            StringEntity s = new StringEntity(jsonObject.toString(), "utf-8");
            s.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,
                    "application/json"));
            //设置参数到请求对象中
            httpPost.setEntity(s);
            System.out.println("请求地址:"+url);
    //        System.out.println("请求参数:"+nvps.toString());
    
            //设置header信息
            //指定报文头【Content-type】、【User-Agent】
    //        httpPost.setHeader("Content-type", "application/x-www-form-urlencoded");
            httpPost.setHeader("Content-type", "application/json");
            httpPost.setHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
            httpPost.setHeader("Authorization","Bearer eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE2NDc1NzE0NTgsInN1YiI6IntcInBob25lXCI6XCIxMzU5MTQ2MjA4OVwiLFwiY29tcGFueUlkXCI6MCxcIm1vZGVsSWRcIjpudWxsLFwiaXNBZG1pblwiOjF9IiwiaWF0IjoxNjE2MDM1NDU4OTU4fQ.Z22zyXgbMraI3EICf0b8j39WAZzMze9srN_CW5PKBhPJp-qEmhaZlrLB98vOAjDnfd8NWuw_bTeio_hHxVz4xg");
    
            //执行请求操作,并拿到结果(同步阻塞)
            CloseableHttpResponse response = client.execute(httpPost);
            //获取结果实体
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                //按指定编码转换结果实体为String类型
                body = EntityUtils.toString(entity, encoding);
            }
            EntityUtils.consume(entity);
            //释放链接
            response.close();
            return body;
        }
    
        /**
         *  描述:发送post请求
         * @param url 请求URL
         * @param param 请求参数 key:value url携带参数 或者无参可不填
         * @author zhouziwei
         * @date 2021/3/10 17:56
         */
        public static String doPost(String url, Map<String, String> param) {
            // 创建Httpclient对象
            CloseableHttpClient httpClient = HttpClients.createDefault();
            CloseableHttpResponse response = null;
            String resultString = "";
            try {
                // 创建Http Post请求
                HttpPost httpPost = new HttpPost(url);
                // 创建参数列表
                if (param != null) {
                    List<NameValuePair> paramList = new ArrayList<>();
                    for (String key : param.keySet()) {
                        paramList.add(new BasicNameValuePair(key, param.get(key)));
                    }
                    // 模拟表单
                    UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
                    httpPost.setEntity(entity);
                }
                // 执行http请求
                response = httpClient.execute(httpPost);
                resultString = EntityUtils.toString(response.getEntity(), "utf-8");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    response.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
    
            return resultString;
        }
    
    
        /**
         * 发送post 请求
         * @param url 请求地址
         * @param json 请求参数
         * @return
         */
        public static String doPostJson(String url, String json) {
            // 创建Httpclient对象
            CloseableHttpClient httpClient = HttpClients.createDefault();
            CloseableHttpResponse response = null;
            String resultString = "";
            try {
                // 创建Http Post请求
                HttpPost httpPost = new HttpPost(url);
                // 创建请求内容
                StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
                httpPost.setEntity(entity);
                // 执行http请求
                response = httpClient.execute(httpPost);
                resultString = EntityUtils.toString(response.getEntity(), "utf-8");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    response.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            return resultString;
        }
    }
    

    OK!

       } finally {
            try {
                response.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
        return resultString;
    }
    
    
    /**
     * 发送post 请求
     * @param url 请求地址
     * @param json 请求参数
     * @return
     */
    public static String doPostJson(String url, String json) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            // 创建请求内容
            StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
            httpPost.setEntity(entity);
            // 执行http请求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return resultString;
    }
    

    }

    
    # OK!
    
    
    
    
    展开全文
  • 实现发送给朋友和分享到朋友圈时内容参数自定义 一、微信JS-SDK 获得Access Token access token的获得方法在前面有介绍,详情见 微信公众平台开发(26) ACCESS TOKEN. 获取jsapi_ticket 生成签名之前必须先了解...
  • 一、需求 分享的是当前页面,可自定义标题,副标题,图片,链接url; 这里最好让后端出个...这里只分享到朋友,QQ,朋友圈,QQ空间 main.js 全局配置分享 三、过程 安装weixin-js-sdk npm install weixin-js-sdk
  • H5分享到微信好友朋友圈QQ好友QQ空间微博二维码这是分享按钮:&lt;button onclick="call()"&gt;通用分享&lt;/button&gt; &lt;button onclick="call('wechatFriend')"&...
  • 需求:成功分享到朋友圈才能领到微信立减金 1、先封装一个公共的js,用来分享 function shareFirend(callBack) { let url = window.location.href.replace(/#.+/, ''); url = encodeURIComponent(url) //请求
  • H5分享,自定义缩略图,分享到微信好友,朋友圈
  • 在页面加载完成后,右上角有个“...”,普通的页面可以在onShareAppMessage()和onShareTimeline()两个方法中分别配置分享给好友/分享到朋友圈的功能。 左一截图的效果是 普通page+安卓手机,这两个按钮在安卓手机...
  • h5+分享到微信、朋友圈代码示例 在使用分享功能的时候会莫名的分享失败,debug时发现是图片过大的问题。 图片过大时ios平台上返回错误码-8,安卓上返回错误码-3(我测试是这样) 因此如果第一次分享失败时递归重新...
  • h5+分享到微信、朋友圈代码示例

    万次阅读 2017-06-29 14:13:06
    h5微信分享
  • 我们可以直接把以下代码加入页面中,即可限制住各类分享。 <script> function onBridgeReady() { WeixinJSBridge.call('hideOptionMenu'); } if (typeof WeixinJSBridge == "undefined...
  • 最近产品部出了一个需求,要做一个分享的功能、在客户端微信上面打开弹出一个h5的分享弹窗,点击可以分享到微信朋友及朋友圈分享出去一张图片,如下图: 当时就想到,一般不都是微信中右上角有个三个点,点击可以...
  • <script type="text/javascript"> console.log('huati') wx.config({ debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log...
  • 实现H5纯静态页面分享到微信朋友圈带图片显示需要前提条件 1、微信公众号已成功认证 2、微信公众号中添加js安全域名 3、添加ip白名单(服务器外网ip) HTML代码部分
  • h5分享到QQ,微信好友,朋友圈

    千次阅读 2019-08-13 16:01:37
    使用:由于微信没有开放直接调起发送给朋友或者朋友圈等权限,因此只能引导用户点击右上角...再手动分享,我们要做的就是 初始化分享出去的内容。 1 首先声明一个变量以供使用 2内容参数:一般设置如下几个 ...
  • 微信H5页面分享朋友圈分享朋友的JS代码。大家一起共勉
  • 找到已有公众号的appid,根据这个appid和url向后端发起请求,拿配置所需要的参数:timestamp、noncestr和signature。 二、实现 1、页面引入JS-SDK文件 通过script标签,引入微信官网的JS-SDK文件 <script ...

空空如也

空空如也

1 2 3 4 5 ... 11
收藏数 201
精华内容 80
关键字:

h5分享到朋友圈