#创作挑战赛#

微信公众号开发过程中必须要在公众号后台设置网页授权域名、JS接口域名和业务域名。比如:h5.juejin.cn。

微信的匹配规则是完全匹配,比如: test.h5.juejin.cn 是不会通过的。

下面使用 nginx 反向代理实现同一个域名既可以访问正式版,也可以访问测试版。

nginx 配置

server { listen 80; server_name h5.juejin.cn; ### 判断是否跳转到确认页面 开始 start ======== set $condiction 'noReferer'; if ($http_referer){ set $condiction ''; } ## 打开微信聊天记录中的链接时,微信会先显示一个外链提示页面,点击 继续访问 才能打开网页。此时 Referer = https://weixin110.qq.com/。 if ($http_referer = "https://weixin110.qq.com/") { set $condiction 'noReferer'; } ## 忽略掉访问 /dev-tool 开头的请求 if ($uri ~* "dev-tool(.*)") { set $condiction "$condiction ignoreUri"; } if ($http_cookie ~* "env=(. ?)(?=;|$)") { #### cookie 中包含“测试环境”标识 set $condiction '$condiction isTest'; } if ($http_cookie ~* "ignoreConfirm=(. ?)(?=;|$)") { #### cookie 中包含“首次访问测试环境忽略提示页面”标识 set $condiction '$condiction ignoreConfirm'; } if ($condiction = 'noReferer isTest') { #### 满足条件1(打开网页)、 条件2(测试环境)时跳转到提示页面 rewrite ^/(.*) /dev-tool?redirect=$request_uri redirect; } #### 判断是否跳转到确认页面 结束 end ======== location / { #### 清除 cookie 中的“首次访问测试环境忽略提示页面”标识 add_header Set-Cookie 'ignoreConfirm=true;expires=Thu, 09 Dec 1970 06:05:42 GMT;path=/'; #### 判断是否使用测试版 开始 start ======== if ($http_cookie ~* "env=(. ?)(?=;|$)") { # proxy_pass http://localhost:7001; proxy_pass http://localhost:11000; } #### 判断是否使用测试版 结束 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用 结束 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用 结束 end ======== } location /dev-tool { root dev-tool; index index.html index.htm; } location = /test { ### 访问测试环境,使用cookie标识访问的是测试环境;cookie过期时间设置为1000年; add_header Set-Cookie 'env=test333;expires=Thu, 09 Dec 3021 06:05:42 GMT;path=/'; ### 首次开启测试环境时增加“忽略提示页面”标识 add_header Set-Cookie 'ignoreConfirm=true;expires=Thu, 09 Dec 3021 06:05:42 GMT;path=/'; rewrite ^/(.*) / redirect; } }

nginx 文件目录:

nginx网站搭建 使用nginx实现在同一个微信公众号授权域名下访问正式版和测试版(1)

dev-tool 文件夹目录结构:

注意在根目录 dev-tool 中还有文件夹 dev-tool

nginx网站搭建 使用nginx实现在同一个微信公众号授权域名下访问正式版和测试版(2)

index.html 文件内容见附录:index.html本地测试

所需软件: SwitchHosts

1. 将 h5.juejin.cn 解析到本地ip

# 172.16.3.1 换成自己机器的ip,使用 127.0.0.1 也可以,如果要支持手机访问,必须指定 ip 172.16.3.16 h5.juejin.cn

nginx网站搭建 使用nginx实现在同一个微信公众号授权域名下访问正式版和测试版(3)

2. 配置 nginx

将 配置 粘贴到 nginx.conf 文件中

3. 将网页放入对应目录中4。浏览器访问

正式版:http://h5.juejin.cn

测试版:http://h5.juejin.cn/test

附赠小知识nginx 中的 或 (||)、且(&&)运算

nginx 中没有或、且运算符,使用以下方式代替:

location /{ set $condiction ''; if ($http_referer = ''){ #### 打开网页或刷新网页时 Referer 表头为空 set $condiction 'noReferer'; } if ($http_cookie ~* "env=(. ?)(?=;|$)"){ set $condiction '$condiction isTest'; } if ($condiction = 'noReferer isTest'){ #### 满足条件1(打开网页或刷新网页)、 条件2(测试环境)时跳转到提示页面 rewrite ^/(.*) /dev-tool?redirect=$request_uri redirect; } }

判断请求 cookie 中是否包含测试环境标识:

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 文件内容:

<!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> /* 设置cookie name:键 value:值 expire:过期时间 */ 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(); }; //根据键获取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('你正在访问测试版,是否继续?', { 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 版本,使用这个 nginx 配置会报 404

location / { set $condiction ''; if ($http_referer = ''){ #### 打开网页或刷新网页时 Referer 表头为空 set $condiction 'noReferer'; } }

可以改为这样:

location / { set $condiction 'noReferer'; if ($http_referer){ set $condiction ''; } }

问题二:访问页面路径返回404, uni-app 打包出来的 H5 版本,直接访问访问某个页面的链接时,使用这个 nginx 配置会报 404

问题描述:

部署 uni-app 打包出来的 H5 版本(目前只测试了这个,其他未测试)访问首页没问题, 如: http://h5.juejin.cn访问页面路径报错 404,如:http://h5.juejin.cn/pages/mine/index

错误原因:

if 指令在 location 上下文中使用会有些问题。官网文档:If is Evil… when used in location context

解决方法:

把部分 if 指令放到 server 上下文中

解决此问题感谢:

  1. try-files-always-returns-404-with-variable

修改前(前往修改后):

server { listen 80; server_name h5.juejin.cn; location / { #### 判断是否跳转到确认页面 开始 start ======== # ============================================ uni-app 打包出来的 H5 版本,使用这个会报 404 # set $condiction ''; # if ($http_referer = ''){ # set $condiction 'noReferer'; # } # ===================================================== set $condiction 'noReferer'; if ($http_referer){ #### 打开网页或刷新网页时 Referer 表头为空 set $condiction ''; } if ($http_cookie ~* "env=(. ?)(?=;|$)"){ #### cookie 中包含“测试环境”标识 set $condiction '$condiction isTest'; } if ($http_cookie ~* "ignoreConfirm=(. ?)(?=;|$)"){ #### cookie 中包含“首次访问测试环境忽略提示页面”标识 set $condiction '$condiction ignoreConfirm'; } #### 清除 cookie 中的“首次访问测试环境忽略提示页面”标识 add_header Set-Cookie 'ignoreConfirm=true;expires=Thu, 09 Dec 1970 06:05:42 GMT;path=/'; if ($condiction = 'noReferer isTest'){ #### 满足条件1(打开网页)、 条件2(测试环境)时跳转到提示页面 rewrite ^/(.*) /dev-tool?redirect=$request_uri redirect; } #### 判断是否跳转到确认页面 结束 end ======== #### 判断是否使用测试版 开始 start ======== if ($http_cookie ~* "env=(. ?)(?=;|$)"){ # proxy_pass http://localhost:7001; proxy_pass http://localhost:11000; } #### 判断是否使用测试版 结束 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用 结束 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用 结束 end ======== } location /dev-tool{ root dev-tool; index index.html index.htm; } location = /test{ ### 访问测试环境,使用cookie标识访问的是测试环境;cookie过期时间设置为1000年; add_header Set-Cookie 'env=test;expires=Thu, 09 Dec 3021 06:05:42 GMT;path=/'; ### 首次开启测试环境时增加“忽略提示页面”标识 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; ### 判断是否跳转到确认页面 开始 start ======== set $condiction 'noReferer'; if ($http_referer){ set $condiction ''; } ## 打开微信聊天记录中的链接时,微信会先显示一个外链提示页面,点击 继续访问 才能打开网页。此时 Referer = https://weixin110.qq.com/。 if ($http_referer = "https://weixin110.qq.com/") { set $condiction 'noReferer'; } ## 忽略掉访问 /dev-tool 开头的请求 if ($uri ~* "dev-tool(.*)") { set $condiction "$condiction ignoreUri"; } if ($http_cookie ~* "env=(. ?)(?=;|$)") { #### cookie 中包含“测试环境”标识 set $condiction '$condiction isTest'; } if ($http_cookie ~* "ignoreConfirm=(. ?)(?=;|$)") { #### cookie 中包含“首次访问测试环境忽略提示页面”标识 set $condiction '$condiction ignoreConfirm'; } if ($condiction = 'noReferer isTest') { #### 满足条件1(打开网页)、 条件2(测试环境)时跳转到提示页面 rewrite ^/(.*) /dev-tool?redirect=$request_uri redirect; } #### 判断是否跳转到确认页面 结束 end ======== location / { #### 清除 cookie 中的“首次访问测试环境忽略提示页面”标识 add_header Set-Cookie 'ignoreConfirm=true;expires=Thu, 09 Dec 1970 06:05:42 GMT;path=/'; #### 判断是否使用测试版 开始 start ======== if ($http_cookie ~* "env=(. ?)(?=;|$)") { # proxy_pass http://localhost:7001; proxy_pass http://localhost:11000; } #### 判断是否使用测试版 结束 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用 结束 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用 结束 end ======== } location /dev-tool { root dev-tool; index index.html index.htm; } location = /test { ### 访问测试环境,使用cookie标识访问的是测试环境;cookie过期时间设置为1000年; add_header Set-Cookie 'env=test333;expires=Thu, 09 Dec 3021 06:05:42 GMT;path=/'; ### 首次开启测试环境时增加“忽略提示页面”标识 add_header Set-Cookie 'ignoreConfirm=true;expires=Thu, 09 Dec 3021 06:05:42 GMT;path=/'; rewrite ^/(.*) / redirect; } }

,