微信公眾號(hào)開發(fā)過程中必須要在公眾號(hào)后臺(tái)設(shè)置網(wǎng)頁授權(quán)域名、JS接口域名和業(yè)務(wù)域名。比如:h5.juejin.cn。
微信的匹配規(guī)則是完全匹配,比如: test.h5.juejin.cn 是不會(huì)通過的。
下面使用 Nginx 反向代理實(shí)現(xiàn)同一個(gè)域名既可以訪問正式版,也可以訪問測(cè)試版。
nginx 配置
server {
listen 80;
server_name h5.juejin.cn;
### 判斷是否跳轉(zhuǎn)到確認(rèn)頁面 開始 start ========
set $condiction 'noReferer';
if ($http_referer){
set $condiction '';
}
## 打開微信聊天記錄中的鏈接時(shí),微信會(huì)先顯示一個(gè)外鏈提示頁面,點(diǎn)擊 繼續(xù)訪問 才能打開網(wǎng)頁。此時(shí) Referer = https://weixin110.qq.com/。
if ($http_referer = "https://weixin110.qq.com/") {
set $condiction 'noReferer';
}
## 忽略掉訪問 /dev-tool 開頭的請(qǐng)求
if ($uri ~* "dev-tool(.*)") {
set $condiction "$condiction ignoreUri";
}
if ($http_cookie ~* "env=(.+?)(?=;|$)") {
#### cookie 中包含“測(cè)試環(huán)境”標(biāo)識(shí)
set $condiction '$condiction isTest';
}
if ($http_cookie ~* "ignoreConfirm=(.+?)(?=;|$)") {
#### cookie 中包含“首次訪問測(cè)試環(huán)境忽略提示頁面”標(biāo)識(shí)
set $condiction '$condiction ignoreConfirm';
}
if ($condiction = 'noReferer isTest') {
#### 滿足條件1(打開網(wǎng)頁)、 條件2(測(cè)試環(huán)境)時(shí)跳轉(zhuǎn)到提示頁面
rewrite ^/(.*) /dev-tool?redirect=$request_uri redirect;
}
#### 判斷是否跳轉(zhuǎn)到確認(rèn)頁面 結(jié)束 end ========
location / {
#### 清除 cookie 中的“首次訪問測(cè)試環(huán)境忽略提示頁面”標(biāo)識(shí)
add_header Set-Cookie 'ignoreConfirm=true;expires=Thu, 09 Dec 1970 06:05:42 GMT;path=/';
#### 判斷是否使用測(cè)試版 開始 start ========
if ($http_cookie ~* "env=(.+?)(?=;|$)") {
# proxy_pass http://localhost:7001;
proxy_pass http://localhost:11000;
}
#### 判斷是否使用測(cè)試版 結(jié)束 end ========
root h5;
try_files $uri $uri/ /index.html;
add_header Cache-Control no-store;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
# proxy_set_header Host $host:7001;
#### 微信H5支付 獲取用戶端ip用 結(jié)束 start ========
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Real-Port $remote_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#### 微信H5支付 獲取用戶端ip用 結(jié)束 end ========
}
location /dev-tool {
root dev-tool;
index index.html index.htm;
}
location = /test {
### 訪問測(cè)試環(huán)境,使用cookie標(biāo)識(shí)訪問的是測(cè)試環(huán)境;cookie過期時(shí)間設(shè)置為1000年;
add_header Set-Cookie 'env=test333;expires=Thu, 09 Dec 3021 06:05:42 GMT;path=/';
### 首次開啟測(cè)試環(huán)境時(shí)增加“忽略提示頁面”標(biāo)識(shí)
add_header Set-Cookie 'ignoreConfirm=true;expires=Thu, 09 Dec 3021 06:05:42 GMT;path=/';
rewrite ^/(.*) / redirect;
}
}
nginx 文件目錄:
dev-tool 文件夾目錄結(jié)構(gòu):
注意在根目錄 dev-tool 中還有文件夾 dev-tool
index.html 文件內(nèi)容見附錄:index.html
本地測(cè)試
所需軟件: Releases · oldj/SwitchHosts · GitHub
1. 將 h5.juejin.cn 解析到本地ip
# 172.16.3.1 換成自己機(jī)器的ip,使用 127.0.0.1 也可以,如果要支持手機(jī)訪問,必須指定 ip
172.16.3.16 h5.juejin.cn
2. 配置 nginx
將 配置 粘貼到 nginx.conf 文件中
3. 將網(wǎng)頁放入對(duì)應(yīng)目錄中
4。瀏覽器訪問
正式版:http://h5.juejin.cn
測(cè)試版:http://h5.juejin.cn/test
附贈(zèng)小知識(shí)
nginx 中的 或 (||)、且(&&)運(yùn)算
nginx 中沒有或、且運(yùn)算符,使用以下方式代替:
location /{
set $condiction '';
if ($http_referer = ''){
#### 打開網(wǎng)頁或刷新網(wǎng)頁時(shí) Referer 表頭為空
set $condiction 'noReferer';
}
if ($http_cookie ~* "env=(.+?)(?=;|$)"){
set $condiction '$condiction isTest';
}
if ($condiction = 'noReferer isTest'){
#### 滿足條件1(打開網(wǎng)頁或刷新網(wǎng)頁)、 條件2(測(cè)試環(huán)境)時(shí)跳轉(zhuǎn)到提示頁面
rewrite ^/(.*) /dev-tool?redirect=$request_uri redirect;
}
}
判斷請(qǐng)求 cookie 中是否包含測(cè)試環(huán)境標(biāo)識(shí):
location = /test{
if ($http_cookie ~* "env=(.+?)(?=;|$)"){
add_header Set-Cookie 'env=test1;expire=Tue, 09 Nov 2021 02:39:01 GMT;path=/';
}
}
附錄
dev-tool/dev-tool/index.html 文件內(nèi)容:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>提示</title>
</title>
<link rel="stylesheet" href="https://res.wx.qq.com/open/libs/weui/2.0.1/weui.min.css">
<script type="text/JAVAscript" src="https://res.wx.qq.com/t/wx_fed/cdn_libs/res/weui/1.2.3/weui.min.js"></script>
</head>
<body>
<script>
/*
設(shè)置cookie
name:鍵
value:值
expire:過期時(shí)間
*/
function setCookie(name, value, expire) {
var exp = new Date();
exp.setTime(exp.getTime() + expire * 24 * 60 * 60 * 1000 * 1);
document.cookie = name + "=" + escape(value) + ";expires=" + exp.toGMTString();
};
//根據(jù)鍵獲取cookie
function getCookie(name) {
var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
if (arr = document.cookie.match(reg))
return unescape(arr[2]);
else
return null;
};
//刪除cookie
function delCookie(name) {
var exp = new Date();
exp.setTime(exp.getTime() - 1);
var cval = getCookie(name);
if (cval != null)
document.cookie = name + "=" + cval + ";expires=" + exp.toGMTString() + ";Path=/";
};
function getQueryVariable(variable) {
var url = window.location.href;
var str = url.split('?');
var query = str[1];
var vars = query.split('&');
console.log(query, str, vars);
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split("=");
console.log(pair);
if (pair[0] == variable) {
return pair[1];
}
}
return (false);
}
// console.log(getQueryVariable('redirect'));
// console.log(getQueryVariable("redirect"));
// var redirectUrl = getQueryVariable('redirect');
var redirectUrl = window.location.href.split("redirect=")[1]
console.log(redirectUrl);
function toTest() {
console.log('yes');
window.location.replace(redirectUrl);
}
function toRelese() {
console.log('no');
delCookie("env");
window.location.replace(redirectUrl);
}
weui.confirm('你正在訪問測(cè)試版,是否繼續(xù)?', {
title: '提示',
buttons: [{
label: '訪問正式版',
type: 'default',
onClick: function () { console.log('no'); toRelese(); }
}, {
label: '確定',
type: 'primary',
onClick: function () { console.log('yes'); toTest(); }
}]
});
</script>
</body>
</html>
問題一:uni-App 打包出來的 H5 版本,使用這個(gè) nginx 配置會(huì)報(bào) 404
location / {
set $condiction '';
if ($http_referer = ''){
#### 打開網(wǎng)頁或刷新網(wǎng)頁時(shí) Referer 表頭為空
set $condiction 'noReferer';
}
}
可以改為這樣:
location / {
set $condiction 'noReferer';
if ($http_referer){
set $condiction '';
}
}
問題二:訪問頁面路徑返回404, uni-app 打包出來的 H5 版本,直接訪問訪問某個(gè)頁面的鏈接時(shí),使用這個(gè) nginx 配置會(huì)報(bào) 404
問題描述:
部署 uni-app 打包出來的 H5 版本(目前只測(cè)試了這個(gè),其他未測(cè)試)
訪問首頁沒問題, 如: http://h5.juejin.cn
訪問頁面路徑報(bào)錯(cuò) 404,如:
http://h5.juejin.cn/pages/mine/index
錯(cuò)誤原因:
if 指令在 location 上下文中使用會(huì)有些問題。官網(wǎng)文檔:If is Evil… when used in location context | NGINX
解決方法:
把部分 if 指令放到 server 上下文中
解決此問題感謝:
- try-files-always-returns-404-with-variable @ https://stackoverflow.com/questions/44077452/try-files-always-returns-404-with-variable
- https://segmentfault.com/q/1010000039845108
修改前(前往修改后):
server {
listen 80;
server_name h5.juejin.cn;
location / {
#### 判斷是否跳轉(zhuǎn)到確認(rèn)頁面 開始 start ========
# ============================================ uni-app 打包出來的 H5 版本,使用這個(gè)會(huì)報(bào) 404
# set $condiction '';
# if ($http_referer = ''){
# set $condiction 'noReferer';
# }
# =====================================================
set $condiction 'noReferer';
if ($http_referer){
#### 打開網(wǎng)頁或刷新網(wǎng)頁時(shí) Referer 表頭為空
set $condiction '';
}
if ($http_cookie ~* "env=(.+?)(?=;|$)"){
#### cookie 中包含“測(cè)試環(huán)境”標(biāo)識(shí)
set $condiction '$condiction isTest';
}
if ($http_cookie ~* "ignoreConfirm=(.+?)(?=;|$)"){
#### cookie 中包含“首次訪問測(cè)試環(huán)境忽略提示頁面”標(biāo)識(shí)
set $condiction '$condiction ignoreConfirm';
}
#### 清除 cookie 中的“首次訪問測(cè)試環(huán)境忽略提示頁面”標(biāo)識(shí)
add_header Set-Cookie 'ignoreConfirm=true;expires=Thu, 09 Dec 1970 06:05:42 GMT;path=/';
if ($condiction = 'noReferer isTest'){
#### 滿足條件1(打開網(wǎng)頁)、 條件2(測(cè)試環(huán)境)時(shí)跳轉(zhuǎn)到提示頁面
rewrite ^/(.*) /dev-tool?redirect=$request_uri redirect;
}
#### 判斷是否跳轉(zhuǎn)到確認(rèn)頁面 結(jié)束 end ========
#### 判斷是否使用測(cè)試版 開始 start ========
if ($http_cookie ~* "env=(.+?)(?=;|$)"){
# proxy_pass http://localhost:7001;
proxy_pass http://localhost:11000;
}
#### 判斷是否使用測(cè)試版 結(jié)束 end ========
root h5;
index index.html index.htm;
# try_files $uri $uri/ /index.html;
add_header Cache-Control no-store;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
# proxy_set_header Host $host:7001;
#### 微信H5支付 獲取用戶端ip用 結(jié)束 start ========
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Real-Port $remote_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#### 微信H5支付 獲取用戶端ip用 結(jié)束 end ========
}
location /dev-tool{
root dev-tool;
index index.html index.htm;
}
location = /test{
### 訪問測(cè)試環(huán)境,使用cookie標(biāo)識(shí)訪問的是測(cè)試環(huán)境;cookie過期時(shí)間設(shè)置為1000年;
add_header Set-Cookie 'env=test;expires=Thu, 09 Dec 3021 06:05:42 GMT;path=/';
### 首次開啟測(cè)試環(huán)境時(shí)增加“忽略提示頁面”標(biāo)識(shí)
add_header Set-Cookie 'ignoreConfirm=true;expires=Thu, 09 Dec 3021 06:05:42 GMT;path=/';
rewrite ^/(.*) / redirect;
}
}
修改后:
server {
listen 80;
server_name h5.juejin.cn;
### 判斷是否跳轉(zhuǎn)到確認(rèn)頁面 開始 start ========
set $condiction 'noReferer';
if ($http_referer){
set $condiction '';
}
## 打開微信聊天記錄中的鏈接時(shí),微信會(huì)先顯示一個(gè)外鏈提示頁面,點(diǎn)擊 繼續(xù)訪問 才能打開網(wǎng)頁。此時(shí) Referer = https://weixin110.qq.com/。
if ($http_referer = "https://weixin110.qq.com/") {
set $condiction 'noReferer';
}
## 忽略掉訪問 /dev-tool 開頭的請(qǐng)求
if ($uri ~* "dev-tool(.*)") {
set $condiction "$condiction ignoreUri";
}
if ($http_cookie ~* "env=(.+?)(?=;|$)") {
#### cookie 中包含“測(cè)試環(huán)境”標(biāo)識(shí)
set $condiction '$condiction isTest';
}
if ($http_cookie ~* "ignoreConfirm=(.+?)(?=;|$)") {
#### cookie 中包含“首次訪問測(cè)試環(huán)境忽略提示頁面”標(biāo)識(shí)
set $condiction '$condiction ignoreConfirm';
}
if ($condiction = 'noReferer isTest') {
#### 滿足條件1(打開網(wǎng)頁)、 條件2(測(cè)試環(huán)境)時(shí)跳轉(zhuǎn)到提示頁面
rewrite ^/(.*) /dev-tool?redirect=$request_uri redirect;
}
#### 判斷是否跳轉(zhuǎn)到確認(rèn)頁面 結(jié)束 end ========
location / {
#### 清除 cookie 中的“首次訪問測(cè)試環(huán)境忽略提示頁面”標(biāo)識(shí)
add_header Set-Cookie 'ignoreConfirm=true;expires=Thu, 09 Dec 1970 06:05:42 GMT;path=/';
#### 判斷是否使用測(cè)試版 開始 start ========
if ($http_cookie ~* "env=(.+?)(?=;|$)") {
# proxy_pass http://localhost:7001;
proxy_pass http://localhost:11000;
}
#### 判斷是否使用測(cè)試版 結(jié)束 end ========
root h5;
try_files $uri $uri/ /index.html;
add_header Cache-Control no-store;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
# proxy_set_header Host $host:7001;
#### 微信H5支付 獲取用戶端ip用 結(jié)束 start ========
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Real-Port $remote_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#### 微信H5支付 獲取用戶端ip用 結(jié)束 end ========
}
location /dev-tool {
root dev-tool;
index index.html index.htm;
}
location = /test {
### 訪問測(cè)試環(huán)境,使用cookie標(biāo)識(shí)訪問的是測(cè)試環(huán)境;cookie過期時(shí)間設(shè)置為1000年;
add_header Set-Cookie 'env=test333;expires=Thu, 09 Dec 3021 06:05:42 GMT;path=/';
### 首次開啟測(cè)試環(huán)境時(shí)增加“忽略提示頁面”標(biāo)識(shí)
add_header Set-Cookie 'ignoreConfirm=true;expires=Thu, 09 Dec 3021 06:05:42 GMT;path=/';
rewrite ^/(.*) / redirect;
}
}