在之前我們只能在微信內的網頁中使用微信的開發標簽-小程序跳轉按鈕 <wx-open-launch-weapp>打開小程序,只有這樣一種單一的場景。
而在實際的業務中,我們希望在給用戶發送的營銷短信、郵件或其他渠道如APP打開小程序,以快速獲取用戶流量,完成引流、導購等目的。
近期微信支持URL Scheme打開小程序。
首先我們先來看一下目前微信官方提供的兩種打開微信小程序的方式以及相關適用場景
| 打開方式 | 適用場景 | 場景值 | 使用方式 | 備注 | 官網鏈接 |
|---|---|---|---|---|---|
| URL Scheme | 短信、郵件、等微信外網頁打開小程序 | 1065 | location.href = 'weixin://dl/business/?t= *TICKET*' |
TICKET由服務端接口返回(openlink) | https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/url-scheme/urlscheme.generate.html |
<wx-open-launch-weapp> |
微信內網頁 | 1167 | 頁面配置<wx-open-launch-weapp>標簽 |
需配置JS接口域名或雲開發靜態網站托管綁定的域名下網頁 | https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_Open_Tag.html |
URL Scheme的獲取
方案一通過服務端接口獲取:
ps:怎樣獲取ACCESS_TOKEN,這里就不寫了
請求地址:
POST https://api.weixin.qq.com/wxa/generatescheme?access_token=ACCESS_TOKEN
請求參數:
| 屬性 | 類型 | 默認值 | 必填 | 說明 |
|---|---|---|---|---|
| access_token | string | 是 | 接口調用憑證 | |
| jump_wxa | Object | 否 | 跳轉到的目標小程序信息。 | |
| is_expire | boolean | false | 否 | 生成的scheme碼類型,到期失效:true,永久有效:false。 |
| expire_time | number | 否 | 到期失效的scheme碼的失效時間,為Unix時間戳。生成的到期失效scheme碼在該時間前有效。最長有效期為1年。生成到期失效的scheme時必填。 |
jump_wxa 的結構:
| 屬性 | 類型 | 默認值 | 必填 | 說明 |
|---|---|---|---|---|
| path | string | 是 | 通過scheme碼進入的小程序頁面路徑,必須是已經發布的小程序存在的頁面,不可攜帶query。path為空時會跳轉小程序主頁。 | |
| query | string | 是 | 通過scheme碼進入小程序時的query,最大1024個字符,只支持數字,大小寫英文以及部分特殊字符:!#$&'()*+,/:;=?@-._~ |
請求示例:
{
"jump_wxa":
{
"path": "/pages/tab",
"query": "xx=1&xxx=1"
},
"is_expire":true,
"expire_time":1614059318
}
返回示例:
{
"errcode": 0,
"errmsg": "ok",
"openlink":"weixin://dl/business/?t= *TICKET*",
}
請求代碼:
/**
* 獲取scheme(創建)
* @param array $params
* @return array
* @throws Exception
*/
public function generateScheme(array $params)
{
list($scene, $path, $query, $appid, $expire_time) = $this->getParams($params);
//獲取小程序實例
$app = XXXX;
$tag = $this->setTag($scene, $appid, $path, $query);
//查詢數據庫/緩存
$infoArr = $this->getSchemeByTag($tag);
if ($infoArr) return $infoArr;
/**
* 請求微信接口
*/
$is_expire = $expire_time ? true : false; //到期失效:true,永久有效:false。
$openlink = $this->wxGenerateScheme($is_expire, $expire_time, $path, $query, $app);
//保存到數據庫
$this->create($params, $appid, $openlink, $tag, $is_expire);
$returnArr = [
'is_expire' => $is_expire,
'expire_time' => $expire_time,
'tag' => $tag,
'openlink' => $openlink,
'appid' => $appid,
];
$key = $this->setCacheKey($tag);
$redis->setex($key, $this->setCacheTime($expire_time), json_encode($returnArr));
return $returnArr;
}
/**
* 通過標記獲取openlink
* @param $tag
* @return array|mixed
* @throws UserException
*/
public function getSchemeByTag($tag)
{
$key = $this->setCacheKey($tag);
if ($cache = $redis->get($key)) return json_decode($cache, true);
$info = Scheme::find()->andWhere(['tag' => $tag])->one();
if (empty($info)) return [];
$returnArr = [
'is_expire' => $info->is_expire,
'expire_time' => $info->expire_time,
'tag' => $tag,
'openlink' => $info->openlink,
'appid' => $info->appid,
];
$redis->setex($key, $this->setCacheTime($info->expire_time), json_encode($returnArr));
return $returnArr;
}
/**
* 設置緩存時間,默認緩存360天
* @param null $expire_time
* @return float|int|null
*/
protected function setCacheTime($expire_time = null)
{
return $expire_time ? $expire_time + 60 : mt_rand(3600 * 20 * 360, 3600 * 24 * 360);
}
/**
* 設置唯一標簽
* @param $scene 場景
* @param $appid
* @param $path 小程序頁面路徑
* @param $query 參數
* @return string
*/
protected function setTag($scene, $appid, $path, $query)
{
return md5($scene . $appid . $path . $query);
}
/**
* 請求微信接口
* @param $is_expire 生成的scheme碼類型,到期失效:true,永久有效:false。
* @param $expire_time 到期失效的scheme碼的失效時間,為Unix時間戳。生成的到期失效scheme碼在該時間前有效。最長有效期為1年。生成到期失效的scheme時必填。
* @param $path 通過scheme碼進入的小程序頁面路徑,必須是已經發布的小程序存在的頁面,不可攜帶query。path為空時會跳轉小程序主頁。
* @param $query 通過scheme碼進入小程序時的query,最大1024個字符,只支持數字,大小寫英文以及部分特殊字符:!#$&'()*+,/:;=?@-._~
* @param $app 小程序實例
* @return mixed
* @throws Exception
*/
protected function wxGenerateScheme($is_expire, $expire_time, $path, $query, $app)
{
$arr = [
'is_expire' => $is_expire,
'expire_time' => $expire_time,
'jump_wxa' => [
'path' => $path,
'query' => $query,
]
];
//這里使用了 EasyWeChat
$server = new BaseClient($app);
$result = $server->httpPostJson('https://api.weixin.qq.com/wxa/generatescheme', $arr);
if ($result['errcode'] != 0) {
$msg = $result['errmsg'] . ',errcode:' . $result['errcode'];
throw new Exception($msg);
}
return $result['openlink'];
}
Scheme保存表設計:
CREATE TABLE `cw_scheme` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `appid` varchar(255) NOT NULL DEFAULT '0' COMMENT 'appid', `scene` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8 NOT NULL COMMENT '場景', `tag` char(33) CHARACTER SET utf8mb4 COLLATE utf8 NOT NULL DEFAULT '' COMMENT '標記(唯一,md5(scene+appid+path+query))', `path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8 DEFAULT NULL COMMENT '通過scheme碼進入的小程序頁面路徑,必須是已經發布的小程序存在的頁面,不可攜帶query。path為空時會跳轉小程序主頁。', `query` varchar(1024) DEFAULT NULL COMMENT '通過scheme碼進入小程序時的query,最大1024個字符,只支持數字,大小寫英文以及部分特殊字符:!#$&''()*+,/:;=?@-._~', `is_expire` tinyint(1) unsigned DEFAULT '1' COMMENT '生成的scheme碼類型,到期失效:1,永久有效:0。(注意這個是給微信接口的參數,業務系統不通過這個來判斷)', `expire_time` int(10) unsigned DEFAULT NULL COMMENT '到期失效的scheme碼的失效時間(業務系統通過這個來判斷)', `openlink` varchar(255) NOT NULL COMMENT '微信返回', `created_at` bigint(20) DEFAULT NULL COMMENT '創建時間', `updated_at` bigint(20) DEFAULT NULL COMMENT '修改時間', PRIMARY KEY (`id`), UNIQUE KEY `appid_tag` (`appid`,`tag`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8 COMMENT='scheme方法產生小程序碼';
小程序URL Scheme的使用:
生成的URL Scheme如下所示:weixin://dl/business/?t= *TICKET*
iOS系統支持識別URL Scheme,可在短信等應用場景中直接通過Scheme跳轉小程序。
Android系統不支持直接識別URL Scheme,用戶無法通過Scheme正常打開小程序,開發者需要使用H5頁面中轉,再跳轉到Scheme實現打開小程序,跳轉代碼示例如下:
location.href = 'weixin://dl/business/?t= *TICKET*'
| 端 | 使用方式 | 備注 |
|---|---|---|
| Android | location.href="weixin://dl/business/?t= *TICKET*" |
只有一種方式 |
| IOS | 直接識別URL Scheme 或使用location.href方式 | 兩種方式 |
But, 當我們進行短信,郵件等觸達時,是無法確定用戶所使用的的手機設備是IOS還是Android,
So, 我們從實際的業務觸發,都需要一個H5頁面進行中轉處理。
小程序喚起業務流程圖

通過短信打開小程序:
一般我們在短信中發送出去的鏈接如下:
https://www.cnblogs.com/jxxiaocao?tag=68627b50710d465c3db3f6c3edbfc0c1
這時在h5頁面可以通過tag請求 getSchemeByTag($tag) 接口來獲取 openlink 就可以通過
location.href = 'weixin://dl/business/?t= *TICKET*'
方法來打開小程序了(這里可以做一些過期等其他的判斷處理)
當然也可以把openlink等包含在要發送的短信鏈接上,但總感覺這樣不好
方案二雲開發
文檔地址:
https://developers.weixin.qq.com/miniprogram/dev/wxcloud/guide/staticstorage/jump-miniprogram.html
適用場景:
非個人主體並且已認證的小程序,使用雲開發靜態網站托管的網頁,可以免鑒權跳轉任意合法合規的小程序
