Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
問題
在微信公眾號(hào)開發(fā)中,必須要跟微信服務(wù)進(jìn)行通訊、交互,包括但不限于如下內(nèi)容:
開發(fā)的時(shí)候真的是Ri了Dog了,每次完成某些功能都需要將代碼打包提交到線上測(cè)試,不僅繁瑣,更是增加了調(diào)試的難度和精力!
解決思路
針對(duì)以上問題,可以使用內(nèi)網(wǎng)穿透,讓公眾號(hào)中綁定的域名最終指向我們開發(fā)環(huán)境本地。
通過搜索,發(fā)現(xiàn)natapp和sunny-ngrok這兩款工具可以實(shí)現(xiàn),具體大家可以自行搜索,已經(jīng)有很完善的說明。
本文我們介紹使用開源的內(nèi)網(wǎng)穿透工具/frp+Nginx,自己搭建一個(gè)內(nèi)網(wǎng)穿透隧道,以達(dá)到我們的目的。
定義本文中使用vue2.x開發(fā)公眾號(hào)網(wǎng)頁(yè)應(yīng)用,npm run serve后,本地環(huán)境地址為:
本文中使用Golang開發(fā)公眾號(hào)應(yīng)用服務(wù)端,運(yùn)行端口為:50110,并通過/mpServe接收微信公眾號(hào)服務(wù)器發(fā)來的請(qǐng)求。本文中使用的域名文本中云服務(wù)器的公網(wǎng)Ip:111.112.113.114定億個(gè)小目標(biāo)目標(biāo):準(zhǔn)備已備案的的域名,本文中我會(huì)將自己的域名打碼,使用作為代替。域名備案的云服務(wù)器,公網(wǎng)IP:111.112.113.114。Nginx下載:/en/…Frp下載://fr…
說明:
本文的開發(fā)環(huán)境和云服務(wù)器都是Windows,因此下載的工具都是Windows版本,各位請(qǐng)根據(jù)自己的開發(fā)環(huán)境、云服務(wù)器環(huán)境下載對(duì)應(yīng)的工具版本。本文使用的是阿里云的域名,非阿里云的域名控制臺(tái)可能不一樣,請(qǐng)各位根據(jù)自己的域名控制臺(tái),做相應(yīng)的配置即可。難點(diǎn):
達(dá)成這億個(gè)小目標(biāo),都需要配置什么,以及存在哪些問題需要解決?
來自域名/mpServe的請(qǐng)求,需要用Nginx轉(zhuǎn)發(fā)到后端應(yīng)用的端口:50110;在公眾號(hào)配置中,設(shè)置JS接口安全域名、業(yè)務(wù)域名、網(wǎng)頁(yè)授權(quán)域名為時(shí),微信會(huì)檢測(cè)該域名根目錄下,其指定的隨機(jī)校驗(yàn)文本是否存在,但是我們指向的是50101開發(fā)端口,那么就需要配置Nginx:收到來自/****.txt的請(qǐng)求時(shí),直接返回校驗(yàn)字符串。成功后,發(fā)現(xiàn)使用微信開發(fā)者工具發(fā)現(xiàn)循環(huán)報(bào)錯(cuò):Invalid Host/Origin header該如何處理?關(guān)閉配置即可。開始一、配置并運(yùn)行frp1、frp服務(wù)端
a. 打開服務(wù)端配置文件frps.ini
b. 配置如下:
[common]
# 服務(wù)端監(jiān)聽端口,接收 frpc 的連接,默認(rèn)值:7000
bind_port = 7000
# 為 HTTP 類型代理監(jiān)聽的端口,啟用后才支持 HTTP 類型的代理,未配置則默認(rèn)不啟用
vhost_http_port = 180
# 鑒權(quán)方式: token, oidc
authentication_method = token
# 鑒權(quán)使用的 token 值
token = token_123456789
# 啟用 Dashboard 監(jiān)聽的本地地址
dashboard_addr = 0.0.0.0
# 啟用 Dashboard 監(jiān)聽的本地端口
dashboard_port = 7500
# Dashboard 登錄賬號(hào)
dashboard_user = admin
# Dashboard 登錄密碼
dashboard_pwd = admin
c. 保存后將配置文件frps.ini,以及服務(wù)端可執(zhí)行文件frps.exe 一并上傳到云服務(wù)器。
d. 控制臺(tái)運(yùn)行命令:start frps -c frps.ini,啟動(dòng)成功后如下圖所示:
e. 檢查是否成功:云服務(wù)器中使用瀏覽器打開鏈接:7500,成功打開登錄頁(yè)面即代表成功。(您也可以使用配置文件中設(shè)置的賬號(hào)密碼進(jìn)行登錄)
f.!!!注意!!!:云服務(wù)器安區(qū)組入方向需要添加:端口7000以及端口180允許,如果需要外網(wǎng)訪問,還需要添加端口7500允許。
2、云服務(wù)器中配置Nginx反向代理
a. Nginx增加配置項(xiàng),如下:
# 監(jiān)聽80端口的 test.666.com 域名請(qǐng)求,并轉(zhuǎn)發(fā)到 180 端口
server {
listen 80; # 監(jiān)聽80端口
server_name test.666.com; # 監(jiān)聽的域名
location / {
# 設(shè)置header
proxy_redirect http://$host/ http://$http_host/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
# 轉(zhuǎn)發(fā)到180端口
proxy_pass http://127.0.0.1:180;
}
}
b. 保存配置后,控制臺(tái)運(yùn)行:nginx -s reload讓Nginx重新加載配置。
3、frp客戶端
a. 打開客戶端配置文件frpc.ini
b. 配置如下:
[common]
# 連接服務(wù)端的地址

server_addr = 111.112.113.114
# 連接服務(wù)端的端口
server_port = 7000
# 鑒權(quán)方式:token, oidc,需要和服務(wù)端一致
authentication_method = token
# 鑒權(quán)使用的 token 值,需要和服務(wù)端一致
token = token_123456789
[web01]
type = http
local_ip = 127.0.0.1
local_port = 80
# 域名
custom_domains = test.666.com
c. 保存后配置文件后,在本地環(huán)境中控制臺(tái)運(yùn)行命令:start frpc -c frpc.ini,成功后如下圖所示:
二、本地啟動(dòng)Nginx1. 在Nginx根目錄,控制臺(tái)運(yùn)行命令:start nginx2. 瀏覽器打開鏈接,成功后如下圖所示:
三、設(shè)置域名解析
進(jìn)入域名控制臺(tái),添加一條A記錄,指向云服務(wù)器公網(wǎng)IP即可,不同域名商的后臺(tái)都不一樣,請(qǐng)各位自行設(shè)置。本文中設(shè)置如下:
四、測(cè)試內(nèi)網(wǎng)穿透效果
根據(jù)每個(gè)服務(wù)商的時(shí)間,等待域名解析成功,本文中阿里云大概在10分鐘左右。瀏覽器打開網(wǎng)址,如果成功穿透,即可正常展示本地環(huán)境搭建的Nginx服務(wù),如下:
五、喝杯咖啡,小憩一下
到這里,我們已經(jīng)成功完成自己搭建一個(gè)支持HTTP協(xié)議的內(nèi)網(wǎng)穿透隧道。具體流程如下圖:
看到這里,可能有人會(huì)提出疑問:
帶著以上問題,我們繼續(xù)完成目標(biāo),并且在本文最后給出解釋。
六、完成目標(biāo)1. 完成公眾號(hào)服務(wù)器URL配置:
本地開發(fā)環(huán)境中,本文的服務(wù)端程序,運(yùn)行在50110端口,并通過/mpServe接收來自微信公眾號(hào)服務(wù)的請(qǐng)求。也就是說需要讓微信公眾號(hào)將請(qǐng)求發(fā)送到我們本地環(huán)境的:50110/mpServe這個(gè)位置。
那通過前面的內(nèi)網(wǎng)穿透,是不是讓公眾號(hào)將請(qǐng)求發(fā)送到:50110/mpServe就行?
當(dāng)然不可以,因?yàn)槲⑿殴娞?hào)配置服務(wù)器URL的時(shí)候不允許在鏈接中出現(xiàn)端口......Ri了Dog了 Again
那么我們就讓本地環(huán)境中的Nginx 將/mpServe的數(shù)據(jù)轉(zhuǎn)發(fā)到50110端口不就行了!
a. 本地環(huán)境中Nginx添加配置,如下:
server {
listen 80; # 監(jiān)聽的端口
server_name test.666.com; # 監(jiān)聽的域名
# 將80端口中收到來自 http://test.666.com/mpServe 的數(shù)據(jù),轉(zhuǎn)發(fā)到50110端口
location ^~/mpServe {
proxy_pass http://localhost:50110;
}
}
b. 保存配置后,命令行執(zhí)行命令:nginx -s reload 讓Nginx重新載入配置。
c. 在微信公眾號(hào)中配置服務(wù)器URL,如圖:
!!!注意!!!:本地環(huán)境中50110端口的公眾號(hào)服務(wù)端,需要各位自己處理響應(yīng)微信發(fā)送的Token驗(yàn)證噢,不然穿透是成功的,但是公眾號(hào)不能驗(yàn)證Token,提交會(huì)提示失敗!
到這里,我們已實(shí)現(xiàn)本地環(huán)境中的服務(wù)端能成功接收并回復(fù)微信公眾的發(fā)來的消息請(qǐng)求。
2. 完成公眾號(hào)JS接口安全域名、網(wǎng)頁(yè)授權(quán)域名、業(yè)務(wù)域名設(shè)置時(shí)的隨機(jī)文本校驗(yàn):
這個(gè)圖不陌生吧? 各位在配置公眾號(hào)設(shè)置中JS接口安全域名、網(wǎng)頁(yè)授權(quán)域名、業(yè)務(wù)域名保存的時(shí)候,微信服務(wù)器都會(huì)驗(yàn)證上圖所述的內(nèi)容。
這個(gè)問題很好解決,我們讓Nginx在收到/.txt請(qǐng)求的時(shí)候,直接返回校驗(yàn)字符串不就好了,開始動(dòng)手:
a. 下載文本.txt文本,打開查看文本中的字符串內(nèi)容,文本中的字符串為:,如圖:
b.本地環(huán)境中Nginx添加配置,如下:
server {
listen 80; # 監(jiān)聽的端口
server_name test.666.com; # 監(jiān)聽的域名
# 將80端口中收到來自 http://test.666.com/mpServe 的數(shù)據(jù),轉(zhuǎn)發(fā)到50110端口
location ^~/mpServe {
proxy_pass http://localhost:50110;
}
# ======= 以下為新增的配置 =======

# 在80端口中收到 http://test.666.com/MP_verify_3wl6rZgobo3WEMaA.txt 請(qǐng)求時(shí),直接返回字符串 '3wl6rZgobo3WEMaA'
location ~ ^/MP_verify_3wl6rZgobo3WEMaA.txt {
default_type text/html;
return 200 '3wl6rZgobo3WEMaA';
}
}
c.保存配置后,命令行執(zhí)行命令:nginx -s reload 讓Nginx重新載入配置。
d.公眾號(hào)設(shè)置中提交JS接口安全域名、網(wǎng)頁(yè)授權(quán)域名、業(yè)務(wù)域名設(shè)置即可。
成功后,我們就實(shí)現(xiàn)了可以在本地環(huán)境中調(diào)用JS接口、可以使用進(jìn)行網(wǎng)頁(yè)授權(quán)登錄等操作。
3. 完成訪問域名時(shí),可以訪問到本地開發(fā)環(huán)境中的公眾號(hào)網(wǎng)頁(yè)應(yīng)用,并且無需在本地打包,實(shí)時(shí)熱更新:
其實(shí)到這里,我們將本地的公眾號(hào)網(wǎng)頁(yè)應(yīng)用打包后,放入Nginx中html目錄,使用域名就能成功運(yùn)行本地的網(wǎng)頁(yè)應(yīng)用。
但是,咱的野心不止于此,憑什么每次更新代碼后,還得打包一次?而且這也不好調(diào)試啊!
先看看本文中的網(wǎng)頁(yè)開發(fā)環(huán)境:
本文中使用vue2.x開發(fā)公眾號(hào)網(wǎng)頁(yè)應(yīng)用,npm run serve后,本地環(huán)境地址為:
看到這里,大家應(yīng)該知道了吧,讓Nginx將的請(qǐng)求全部反向代理到50101端口不就好了,開始動(dòng)手:
a. 本地環(huán)境中Nginx添加配置,如下:
server {
listen 80; # 監(jiān)聽的端口
server_name test.666.com; # 監(jiān)聽的域名
# 將80端口中收到來自 http://test.666.com/mpServe 的數(shù)據(jù),轉(zhuǎn)發(fā)到50110端口
location ^~/mpServe {
proxy_pass http://localhost:50110;
}
# 在80端口中收到 http://test.666.com/MP_verify_3wl6rZgobo3WEMaA.txt 請(qǐng)求時(shí),直接返回字符串 '3wl6rZgobo3WEMaA'
location ~ ^/MP_verify_3wl6rZgobo3WEMaA.txt {
default_type text/html;
return 200 '3wl6rZgobo3WEMaA';
}
# ======= 以下為新增的配置 =======
# 將80端口中收到來自 http://test.666.com 的數(shù)據(jù),轉(zhuǎn)發(fā)到50101端口
location / {
proxy_pass http://192.168.2.222:50101; # 這里必須是 192.168.xxx.xxx,不可以是localhost
}
}
b.保存配置后,命令行執(zhí)行命令:nginx -s reload 讓Nginx重新載入配置。
c.打開微信開發(fā)者工具,打開鏈接
搞定!
七、報(bào)錯(cuò):Invalid Host/Origin header
使用打開我們本地環(huán)境中的網(wǎng)頁(yè)應(yīng)用后,無論是微信開發(fā)者工具,還是瀏覽器,控制臺(tái)都會(huì)循環(huán)輸出錯(cuò)誤Invalid Host/Origin header:
這是webpack本身出于安全考慮,檢查header中的Host、Origin不一致,以為是受到攻擊提示從錯(cuò)誤信息。咱這是內(nèi)網(wǎng)穿透,當(dāng)然會(huì)出現(xiàn)這個(gè)問題,所以,禁用掉配置即可。
打開配置文件:
添加如下內(nèi)容:
...
devServer: { // 在devServer配置中
...
disableHostCheck: true, // 新增該配置項(xiàng)
...
}
...
保存配置,重啟npm:npm run serve
刷新微信開發(fā)者工具 或 瀏覽器
搞定,煩人的錯(cuò)誤無了
總結(jié)
到這我們已經(jīng)完成全部目標(biāo),再也不用單獨(dú)寫代碼檢測(cè)開發(fā)環(huán)境和線上環(huán)境了,再也不用頻繁打包上傳到服務(wù)器了,再也不用在線上調(diào)試到抓狂了!!!
下面,來說說前面提到的疑問,為什么云服務(wù)器和本地環(huán)境中為什么不將Nginx這一層直接取消。
先看個(gè)圖:
先說本地環(huán)境:上圖所述,本地環(huán)境中需要針對(duì)/mpServe、/、/.txt 做出不同的轉(zhuǎn)發(fā),使用Nginx就沒什么好說的了。
再說云服務(wù)器:上圖所述,如果服務(wù)器中運(yùn)行了其他的應(yīng)用,那么Nginx還是需要的。如果服務(wù)器中沒有其他應(yīng)用,則完全可以將Nginx這層去掉,將frp服務(wù)端的端口配置為80即可。
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。