客戶端內(nèi)實時調(diào)試H5方案——nginx反向代理的使用

1.背景

移動互聯(lián)網(wǎng)發(fā)展到今天,由于H5的跨平臺、高效率、低成本等優(yōu)勢,我們的前端開發(fā)工作內(nèi)容已不僅僅局限于瀏覽器端的網(wǎng)頁,現(xiàn)在很多應(yīng)用都已經(jīng)引入了新的開發(fā)模式:Hybrid APP。
Hybrid APP底層依賴于Native提供的容器(UIWebview),上層使用HTML、CSS和JavaScript來開發(fā),這樣的方式使得應(yīng)用更新迭代變得更加敏捷和高效,所以Hybrid APP應(yīng)用越來越多。但是隨之而來的會有很多新問題,比如今天我們要談到的實際開發(fā)中前端如何模擬客戶端環(huán)境實時調(diào)試。
傳統(tǒng)的前端開發(fā),在PC端我們可以用瀏覽器直接打開html頁面,實時查看和調(diào)試頁面,移動端可以借助類似BrowserSync這種實時同步工具來調(diào)試,但是在Native下,很多時候我們需要依賴用戶的信息或者依賴客戶端的一些行為,只能先提測或者上線,讓客戶端同學(xué)給配一個測試或線上入口url,每次更新了代碼,都要push代碼,然后在客戶端內(nèi)查看效果,這還只是應(yīng)對新需求未上線的功能,一旦項目上線有bug需要修復(fù),我們沒有客戶端的真實環(huán)境,比如測試環(huán)境沒有正式環(huán)境的某些數(shù)據(jù),很難將問題復(fù)現(xiàn)出來,也不可能拿線上代碼直接去push調(diào)試,所以這種方案顯然不合理。那么有什么辦法能讓我們修改完本地代碼后,直接重載客戶端的Webview,就能實時看到Native中最新效果了呢,下面介紹一種開發(fā)模式,滿足我們的Hybrid H5開發(fā)需求。先來看看一個實際案例:

2.案例描述

前些天測試同學(xué)給我提了個bug單,大概是這樣的:我們的書城客戶端內(nèi)有一個專題,內(nèi)容是一些書籍列表,每個書籍都有一個『閱讀』按鈕,bug現(xiàn)象是“打開的書籍與專題中實際點擊的不一致,打開的是該專題下最后一本書。”。看描述猜測原因應(yīng)該是:點擊閱讀按鈕時候調(diào)用的 readbook() 方法,需要傳入所選書籍信息作為參數(shù),傳參邏輯出現(xiàn)了問題。
因為這個專題模板之前不是我寫的,專題模板又兼容了多類專題,代碼量龐大,所以熟悉了下代碼框架后先基本確認(rèn)了問題點,果然是這里的readbook() 方法的參數(shù)在列表循環(huán)數(shù)據(jù)的時候被覆蓋了,這里需要重新兼容一個邏輯處理,修復(fù)完畢。但是改別人的代碼最擔(dān)心的就是牽一動百,而且這個專題只有線上正式環(huán)境才有,測試環(huán)境沒有,也不想再去麻煩運(yùn)營同學(xué)給測試環(huán)境配一堆數(shù)據(jù),所以問題來了,怎么才能在本地客戶端環(huán)境實時調(diào)試H5而不把風(fēng)險留給正式環(huán)境來測呢?先梳理下思路。

3.思路梳理

我們需要搞清楚兩個問題:
1.如何本地調(diào)取線上環(huán)境接口數(shù)據(jù),沒數(shù)據(jù)我們無法測試該專題;
2.如何將本地代碼實時同步到客戶端內(nèi)訪問。
先看第一個問題,我們的js網(wǎng)絡(luò)協(xié)議層的方案大概是這樣的,先判斷當(dāng)前url域名是不是線上域,是的話就調(diào)正式環(huán)境后端服務(wù)接口,否則就掉測試環(huán)境后端接口,網(wǎng)絡(luò)協(xié)議層一般是不動的,我不能為了測試去修改網(wǎng)絡(luò)層規(guī)則再提測,這也是不合理的,所以解決這個問題的第一步,就是模擬正式域。這里我們的方案思路是使用nginx代理服務(wù)器配合修改hosts文件來實現(xiàn),將正式域名 iyuedu.qq.com 在開發(fā)環(huán)境中直接指向本地代碼,有了這個基礎(chǔ),第二個問題自然想到通過給手機(jī)掛代理來實現(xiàn)。

4.安裝nginx服務(wù)器

首先安裝nginx服務(wù)器,以下演示以Mac為例,Windows下nginx安裝見此。

1.Homebrew安裝

Mac下nginx要通過Homebrew來安裝(簡稱brew),brew是Mac OSX上的軟件包管理工具,能在Mac中方便的安裝軟件或者卸載軟件。
Homebrew的安裝非常簡單,打開終端復(fù)制、粘貼以下命令,回車:

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

brew安裝完畢后,可以在終端輸入命令「brew -v」檢查以下是否安裝成功(若失敗,多試幾次):

返回了Homebrew 1.2.1版本號,說明brew已經(jīng)安裝成功。

2.nginx安裝

接下來繼續(xù)安裝nginx,執(zhí)行命令:

brew search nginx
brew install nginx

可能由于網(wǎng)絡(luò)因素,安裝的時候花費了很長時間,中間失敗了兩次,所以這里如果安裝不順暢,請多嘗試幾次即可。
同樣安裝完畢后我們可以通過命令「nginx -v」查看nginx是否安裝成功:

返回 nginx/1.12.0 版本,搞定。

5.修改ngnix.conf配置

nginx已經(jīng)安裝完畢,但是我們還要通過對nginx的一些配置,讓它使我們的線上域名“ iyuedu.qq.com ”在本機(jī)中指向本地的代碼目錄。
打開Finder,前往文件夾 “/usr/local/etc/nginx/” ,然后找到 nginx.conf 文件,打開并進(jìn)行編輯:
找到 http 下的 server,進(jìn)行如下配置修改:

server {
  listen       80;
  server_name  iyuedu.qq.com; 
  set $path '/Users/luping/Desktop/work/git_code/baipai/oppo-webapp-html/WebContent/6_0/';
  location / {
        root  $path;
        index  index.html index.htm;
        autoindex on;
  }
}

這里我們使用 80 端口,server_name很好理解,就是我們主機(jī)的名稱,我們使用線上域名“iyuedu.qq.com”,然后設(shè)置一個變量$path來保存本地代碼路徑,在location中賦值給root。
保存,關(guān)閉,其他的地方保持原配置暫不用修改。
注意,這里會有兩個坑,后面運(yùn)行的時候再分析解決。

6.修改hosts文件

hosts文件是一個用于儲存計算機(jī)網(wǎng)絡(luò)中各節(jié)點信息的計算機(jī)文件,我們可以配置ip地址和其對應(yīng)主機(jī)名。
打開Finder,前往文件夾 “/private/etc/hosts” ,找到hosts文件,先復(fù)制一份到桌面,然后打開,我們將默認(rèn)的 “127.0.0.1 localhost” 先注釋,再添加一條:

# 127.0.0.1 localhost
127.0.0.1   iyuedu.qq.com

保存后,在粘貼回 “/private/etc/hosts”目錄下,這里需要提供下管理員密碼,繼續(xù)即可。至此我們的hosts文件也修改完畢,將本地的ip對應(yīng)到了我們的想要的正式域名“iyuedu.qq.com”。

7.啟動&解決問題

1.啟動

終于等到這一刻,是時候看一下修煉成果了,我們需要啟動nginx服務(wù),這里先普及下nginx常用的幾個命令:

sudo nginx #打開 nginx
nginx -s reload|reopen|stop|quit  #重新加載配置|重啟|停止|退出 nginx
nginx -t   #測試配置是否有語法錯誤

nginx [-?hvVtq] [-s signal] [-c filename] [-p prefix] [-g directives]

-?,-h           : 打開幫助信息
-v              : 顯示版本信息并退出
-V              : 顯示版本和配置選項信息,然后退出
-t              : 檢測配置文件是否有語法錯誤,然后退出
-q              : 在檢測配置文件期間屏蔽非錯誤信息
-s signal       : 給一個 nginx 主進(jìn)程發(fā)送信號:stop(停止), quit(退出), reopen(重啟), reload(重新加載配置文件)
-p prefix       : 設(shè)置前綴路徑(默認(rèn)是:/usr/local/Cellar/nginx/1.2.6/)
-c filename     : 設(shè)置配置文件(默認(rèn)是:/usr/local/etc/nginx/nginx.conf)
-g directives   : 設(shè)置配置文件外的全局指令

好了,首先我們啟動nginx:

sudo nginx

按照配置,我們把本地的localhost修改為了“iyuedu.qq.com”,然后直接指向了代碼目錄,所以理論上我們打開瀏覽器直接訪問 “http://iyuedu.qq.com/topicV2.html” 就可以訪問到這個專題文件topicV2.html了,試一試:

nginx-403 Forbidden

發(fā)現(xiàn)nginx給我們報了個錯,提示 “403 Forbidden”,目測是權(quán)限問題,nginx不允許查看。看來我們還要再修改一下nginx.conf配置文件,在nginx.conf文件的最頂部加一句

user root owner;

保存,然后在終端重啟nginx:

sudo nginx -s reload

在瀏覽器中再刷新一下:

nginx-success

看樣子好像成了,我們幾乎達(dá)到了目的,本地訪問域名“iyuedu.qq.com”但實際訪問的是本地的代碼,而且顯然已經(jīng)成功的取到了后端線上接口數(shù)據(jù),經(jīng)測試,修改了一下本地代碼,瀏覽器中一刷新,頁面會立刻看到更新改動,這不正是我們想要的嗎,但是,好像還差那么一點點,對比了下這個專題真正的線上url,是這樣的:
http://iyuedu.qq.com/act/6_0/topicV2.html
而我們目前模擬出來的是:
http://iyuedu.qq.com/topicV2.html
對比發(fā)現(xiàn),我們模擬的url缺少了一部分路徑 “/act/6_0”,這樣的話顯然不能進(jìn)行下面的代理客戶端中頁面url的工作了,所以我們必須要模擬得一模一樣!

好吧,我們繼續(xù)填坑。

2.解決,location中root和alias

上面我們只是用nginx和hosts來啟動了服務(wù)和修改了本地ip對應(yīng)的主機(jī)名稱為我們的正式域名,那么繼續(xù)給這個域名配一個虛擬的路徑,誰來做呢?當(dāng)然還是nginx, hosts文件能力有限,只能修改一下主機(jī)名稱,真正挑大梁的還是nginx。
原來nginx.conf中的location指定文件路徑有兩種方式:root和alias。
root與alias主要區(qū)別在于nginx如何解釋location后面的uri,這會使兩者分別以不同的方式將請求映射到服務(wù)器文件上。

[root]
語法:root path
默認(rèn)值:root html
配置段:http、server、location、if
[alias]
語法:alias path
配置段:location

root實例:

location ^~ /path/ {
     root /www/page/html/;
}

如果一個請求的URI是 /path/a.html 時,web服務(wù)器將會返回服務(wù)器上的 /www/page/html/path/a.html 的文件。

alias實例:

location ^~ /path/ {
     alias /www/page/html/;
}

如果一個請求的URI是 /path/a.html 時,web服務(wù)器將會返回服務(wù)器上的/www/page/html/a.html的文件。注意這里是 /www/page/html ,因為alias會把location后面配置的路徑“/path”丟棄掉,把當(dāng)前匹配到的目錄指向到指定的目錄。
知道了這一點,我們要做的就是使用alias修改一下nginx.conf,我們?nèi)鄙俚穆窂绞恰?strong>/act/6_0/”,所以修改如下:

server {
  listen       80;
  server_name  iyuedu.qq.com; 
  set $path '/Users/luping/Desktop/work/git_code/baipai/oppo-webapp-html/WebContent/6_0/';
  location ^~ /oppo/6_0/ {        //  *修改下location*
        alias  $path;                    //  *使用 alias *
        index  index.html index.htm;
        autoindex on;
  }
}

保存nginx.conf文件,然后再次重啟nginx服務(wù):

sudo nginx -s reload

再次回到瀏覽器,我們輸入線上正式的url:
http://iyuedu.qq.com/act/6_0/topicV2.html?tid=327950&tf=1
刷新,頁面正常顯示:


但是,這個頁面訪問的代碼到底是不是我們本地的代碼呢,試一下便知,我們修改下“閱讀”按鈕的文案為“test”,保存看看是否及時生效:

沒毛病,成了,現(xiàn)在我們已經(jīng)完全在本地模擬了線上正式域頁面的url
,也成功取到了線上接口數(shù)據(jù),接下來就是在客戶端內(nèi)實時預(yù)覽這個頁面了。

8.客戶端實時預(yù)覽H5

我們已經(jīng)在本地啟了nginx服務(wù),修改了主機(jī)名為線上域名,所以接下來我們只需要讓手機(jī)和Mac處于同一個局域網(wǎng)內(nèi),并且給手機(jī)掛上代理,就可以在線上包客戶端內(nèi)訪問到我們的本地代碼頁面了,有了客戶端環(huán)境,我們就可以更方便地進(jìn)行調(diào)試了,這正是我們想要的。
給手機(jī)掛代理,我們需要在電腦上啟動一個常用的抓包軟件,Mac上我用的是 Charles,Windows下一般是Fiddler,啟動后一般默認(rèn)端口是8888,當(dāng)然也可以自己修改,這里我們就不修改直接使用默認(rèn)的端口號8888。
然后再找一下電腦當(dāng)前的ip,Mac-設(shè)置-網(wǎng)絡(luò) 就可以看到我的是192.168.1.112。

注意,有的公司的內(nèi)部局域網(wǎng)考慮安全因素設(shè)置了比如AP隔離等,導(dǎo)致連接到同一局域網(wǎng)內(nèi)的設(shè)備不能互相通信,當(dāng)然也不能進(jìn)行抓包等操作,這種情況下需要我們使用電腦開啟網(wǎng)絡(luò)熱點來讓移動設(shè)備連接,關(guān)于Windows和Mac開啟熱點的方式:
Windows用戶看這里
Mac用戶看這里

拿出我們的手機(jī),連接到與當(dāng)前電腦同一個wifi局域網(wǎng),對該wifi網(wǎng)絡(luò)進(jìn)行高級設(shè)置-代理,主機(jī)名輸入我們的電腦IP,端口輸入8888,然后確定保存,這時我們的手機(jī)就已經(jīng)掛上代理了。
然后打開app客戶端,找到這個專題,點擊進(jìn)去,發(fā)現(xiàn)這個頁面的“閱讀”按鈕的文案已經(jīng)是“test”了,說明我們的客戶端由于手機(jī)掛上了我們的本地網(wǎng)絡(luò)代理,url自動指向了本地代碼目錄。這樣,我們的終極目標(biāo)就達(dá)到了,現(xiàn)在客戶端環(huán)境下,我們已經(jīng)可以隨時調(diào)試本地的H5代碼了。

9.小結(jié)

這只是一個開發(fā)模式上的優(yōu)化方案,雖然略復(fù)雜麻煩一些,但是也大大提高了開發(fā)的效率和可靠性,也切實為我們解決了一些棘手的問題。由于本人經(jīng)驗和能力有限,文中提到的一些地方如有描述不準(zhǔn)確或者錯誤的地方,歡迎大家指正,也相信還有更加便捷的方法來實現(xiàn)這個需求,先這樣吧,88。 [愉快]

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,732評論 6 539
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,214評論 3 426
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,781評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,588評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 72,315評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,699評論 1 327
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,698評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,882評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,441評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,189評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,388評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,933評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,613評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,023評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,310評論 1 293
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,112評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,334評論 2 377

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,818評論 18 139
  • 上一篇《WEB請求處理一:瀏覽器請求發(fā)起處理》,我們講述了瀏覽器端請求發(fā)起過程,通過DNS域名解析服務(wù)器IP,并建...
    七寸知架構(gòu)閱讀 81,121評論 21 356
  • 第一章 Nginx簡介 Nginx是什么 沒有聽過Nginx?那么一定聽過它的“同行”Apache吧!Ngi...
    JokerW閱讀 32,740評論 24 1,002
  • 今天是西洋的感恩節(jié),網(wǎng)絡(luò)上、群組上流傳了很多感恩的文字,「感恩」在今天似手是顯得特別的耀眼。 在這美好的感恩時刻,...
    周明達(dá)老師閱讀 1,361評論 5 11
  • 姓名:梁德寶 單位:寧波大發(fā)化纖有限公司 組名:樂觀一組 期數(shù):六項精進(jìn)234期學(xué)員 日精進(jìn)打卡第56天 【知~學(xué)...
    梁德寶閱讀 135評論 0 0