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

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

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