SoFunction
Updated on 2025-04-06

Detailed explanation of the problem of calling WeChat jssdk in vue development

cause

You cannot share pictures when sharing URLs on WeChat, and this problem needs to be solved with jssdk. In fact, you can see pictures at the beginning, but later on WeChat banned it. So you can only use jssdk to solve it.
Ordinary web page development is very simple, but there will be problems when using vue or other front-end frameworks to develop spa single-page webapps. As long as the url changes, a signature error will be reported. In fact, the official WeChat account has written an explanation.

All pages that need to use JS-SDK must be injected with configuration information first, otherwise they will not be called (the same url needs to be called once. The web app of the SPA that changes the url can be called every time the url changes. Currently, the Android WeChat client does not support the new H5 feature of pushState, so using pushState to implement the web app will cause signature failure, and this problem will be fixed in Android 6.2).
But these instructions are all the same (but they are of no use).

The root of the problem

1 The same url needs to be called only once. The web app of the SPA that changes the url can be called every time the url changes.
If your linking hash method, you need to call it again if the anchor point changes, because the URL has changed. This can be placed in the router's listening event, such as watching $route, or using the beforeRouteUpdate guard introduced in 2.2.

2 The URL cannot contain anchor points when generating the signature
The signature of WeChat jssdk needs to be generated by the server, so we need to pass the URL of the current page to the server, and the server generates the parameters required for initialization.
However, you need to pay attention to the URL when passing it, and you must not have an anchor link. You can use ('#')[0] to get the part before the anchor in the url.
For example, your website is/#/food/1
You just need to/Pass it to the server and let the server generate a signature. When calling jssdk, you can add an anchor link to the URL.

Example

Install jssdk

npm install weixin-js-sdk --save

Previous code

export default {
  mounted() {
   this.$nextTick(function () {
    ()
   })
  },
  data () {
   return {
    detail: [],
   }
  },
  methods: {   
   // WeChat parameters   getConfig() { 
    let url = ('#')[0] //Get the link before the anchor    this.$('/',{
     params: {
      url: url
     }
    }).then(response => {
      let res = ;
      (res);
     })
   },
   // Share on WeChat   wxInit(res) {
    let url = ('#')[0] //Get the link before the anchor    let links = url+'#/Food/' + this.$;
    let title =  + '-Purethrine';
    let desc = 'To learn more, please follow the "Purerine Chain" official account';
    let imgUrl = ;
    ({
     debug: false,
     appId: ,
     timestamp: ,
     nonceStr: ,
     signature: ,
     jsApiList: ['onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareWeibo', 'onMenuShareQZone']
    });
    (function() {
     ({
      title: title, // Share the title      desc: desc, // Share the description      link: links, // Share link      imgUrl: imgUrl, // Share icon      success: function() {
// alert("Shared to Moments successfully")       //Toast({
        //message: "Successfully shared to friends"       //});
      },
      cancel: function() {
// alert("Share failed, you canceled the sharing!")       //Toast({
        //message: "Share failed, you canceled the sharing!"       //});
      }
     });
     //WeChat sharing menu test     ({
      title: title, // Share the title      desc: desc, // Share the description      link: links, // Share link      imgUrl: imgUrl, // Share icon      success: function() {
       // alert("Successfully shared with friends")//       Toast({
// message: "Successfully shared with friends"//       });
      },
      cancel: function() {
       // alert("Share failed, you canceled the sharing!")//       Toast({
// message: "Share failed, you canceled the sharing!"//       });
      }
     });

     ({
      title: title, // Share the title      desc: desc, // Share the description      link: links, // Share link      imgUrl: imgUrl, // Share icon      success: function() {
       // alert("Successfully shared with QQ")//       Toast({
// message: "Successfully shared to QQ"//       });
      },
      cancel: function() {
       // alert("Share failed, you canceled the sharing!")//       Toast({
// message: "Share failed, you canceled the sharing!"//       });
      }
     });
     ({
      title: title, // Share the title      desc: desc, // Share the description      link: links, // Share link      imgUrl: imgUrl, // Share icon      success: function() {
       // alert("Successfully shared with friends")//       Toast({
// message: "Successfully shared to Tencent Weibo"//       });
      },
      cancel: function() {
       // alert("Share failed, you canceled the sharing!")//       Toast({
// message: "Share failed, you canceled the sharing!"//       });
      }
     });
     ({
      title: title, // Share the title      desc: desc, // Share the description      link: links, // Share link      imgUrl: imgUrl, // Share icon      success: function() {
       // alert("Successfully shared with friends")//       Toast({
// message: "Successfully shared to QQ space"//       });
      },
      cancel: function() {
       // alert("Share failed, you canceled the sharing!")//       Toast({
// message: "Share failed, you canceled the sharing!"//       });
      }
     });

    });
    (function(err) {
     alert((err))
    });
   }
  }
 }

Page code

// Official instance, generate the required configuration informationclass JSSDK {
 private $appId;
 private $appSecret;

 public function __construct($appId, $appSecret) {
  $this->appId = $appId;
  $this->appSecret = $appSecret;
 }

 public function getSignPackage() {
  $jsapiTicket = $this->getJsApiTicket();

  // Note that URLs must be obtained dynamically, and cannot be hardcoded.  $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
  // Note that this is the key point  $url = !empty($_GET['url']) ? $_GET['url'] : "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";

  $timestamp = time();
  $nonceStr = $this->createNonceStr();

  // The order of parameters here must be sorted in ascending order of key value ASCII code  $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 should be stored and updated globally, the following code is written to the file for example  $data = json_decode($this->get_php_file("jsapi_ticket.php"));
  if ($data->expire_time < time()) {
   $accessToken = $this->getAccessToken();
   // If it is a corporate account, use the following URL to obtain the ticket   // $url = "/cgi-bin/get_jsapi_ticket?access_token=$accessToken";
   $url = "/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;
    $this->set_php_file("jsapi_ticket.php", json_encode($data));
   }
  } else {
   $ticket = $data->jsapi_ticket;
  }

  return $ticket;
 }

 private function getAccessToken() {
  // access_token should be stored and updated globally. The following code is written to the file for example  $data = json_decode($this->get_php_file("access_token.php"));
  if ($data->expire_time < time()) {
   // If it is an enterprise account, use the following URL to obtain access_token   // $url = "/cgi-bin/gettoken?corpid=$this->appId&corpsecret=$this->appSecret";
   $url = "/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;
    $this->set_php_file("access_token.php", json_encode($data));
   }
  } 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);
  // To ensure the security of data transmission between a third-party server and a WeChat server, all WeChat interfaces are called using https, and the following 2 lines of code must be used to open SSL security verification.  // If the code fails to verify here during deployment, please go to /ca/ to download the new certificate discrimination file.  curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
  curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, true);
  curl_setopt($curl, CURLOPT_URL, $url);

  $res = curl_exec($curl);
  curl_close($curl);

  return $res;
 }

 private function get_php_file($filename) {
  return trim(substr(file_get_contents($filename), 15));
 }
 private function set_php_file($filename, $content) {
  $fp = fopen($filename, "w");
  fwrite($fp, "<?php exit();?>" . $content);
  fclose($fp);
 }
}



// Logical code$appId = 'Your appid';
$appSecret = 'Your appSecret';
$jssdk = new JSSDK($appId, $appSecret);
$signPackage = $jssdk->GetSignPackage();
echo json_encode($signPackage);

I saw that the above class uses $_GET['url'] to receive data transmitted from the previous section.

The above is a detailed explanation and integration of the problem of calling WeChat jssdk in vue development introduced to you by the editor. I hope it will be helpful to you. If you have any questions, please leave me a message and the editor will reply to you in time. Thank you very much for your support for my website!