如何用Nginx來助力前端開發

 

 

“誰說前端需要懂Nginx了?”

“前端憑什麼要學習Nginx?”

“不用Nginx,我們前端的日子不也是照過嗎?”

在找 nginx 文章的時候,經常看到類似的標題......我只想說一句——

 

 

 

很多前端開發者一直對 Nginx 有誤會,認爲 Nginx 是偏後端的知識,我們前端不需要懂,更沒必要去使用它。

但是等筆者熟悉了 Nginx 之後,發現其實用好 Nginx 可以解放我們的前端生產力,用來助力我們的前端開發。(對 Nginx 不熟的點這裏

 

1. 快速部署靜態應用

這個場景自不必說,Nginx 本身就是一個 web 服務器。

Nginx 部署靜態應用只需要改一行配置,而我們前端號稱“終將統一宇宙”的 Node.js 至少也需要6行代碼。

這裏當然不是在比較孰優孰劣的問題,只是在靜態應用部署這塊,Nginx 使起來確實要更快速、方便。

參考代碼:

# 首尾配置暫時忽略
server {  
        listen       8080;        
        server_name  localhost;

        location / {
            # root   html; # Nginx默認路徑
            root /usr/local/var/www/my-project; # 設置爲個人項目的根目錄路徑
            index  index.html index.htm;
        }
}
# 首尾配置暫時忽略
複製代碼

只需要將 root 屬性值改爲你要部署的絕對路勁(我的是/usr/local/var/www/my-project)即可。

2. 請求過濾

設置訪問白名單

當你的項目沒有灰度環境,又想在功能上線後先讓測試同事試用一下的時候,就需要設置訪問的白名單了。

如果你的項目用上了 nginx 做代理,你就會發現這就是小菜一碟。

參考代碼:

# 首尾配置暫時忽略
server {
        listen       8080;        
        server_name  localhost;

        location / {
            # IP訪問限制(只允許IP是 10.81.1.11 的機器才能訪問)
            allow 10.81.1.11;
            deny all;
            
            root   html;
            index  index.html index.htm;
        }
}
# 首尾配置暫時忽略
複製代碼

上面代碼塊中的IP改成你們測試同事機器的IP即可。Nginx 這種顧名思義、一目瞭然的配置連講解都顯得很多餘。

講到這,我腦子裏突然閃過《舌尖上的中國》中的一句話:

高端的食材,往往只需要採用最簡單的烹飪方式。

配置圖片防盜鏈

筆者剛參加工作之初遇到過這個問題:

爲了不等設計師出圖,便想先開發完功能再替換圖片。這時候我將從百度找到尺寸差不多的圖片引入項目中,竟然發現圖片不能正常顯示,提示“該圖片僅限百度內部用戶交流使用”。最後不得不下載這張圖片,放入項目中使用。

後來經驗漸長,我明白了這是因爲百度將圖片做了防盜鏈處理,不允許別的網站以外鏈的方式進行引用。

那麼當我們的項目也想保護自己的圖片權益,設置圖片防盜鏈的時候我們怎麼實現呢?

# 首尾配置暫時忽略
server {
        listen       8080;        
        server_name  localhost;

        location / {
            root   /usr/local/var/www/my-project; # 設置爲個人項目的根目錄路徑
            index  index.html index.htm;
        }
        
        # 圖片防盜鏈
        location ~* \.(gif|jpg|jpeg|png|bmp|swf)$ {
            valid_referers none blocked 192.168.0.103; # 只允許本機IP外鏈引用
            if ($invalid_referer){
                return 403;
            }
        }
}
# 首尾配置暫時忽略
複製代碼

上面代碼塊設置了只允許本機IP外鏈引用圖片資源,其他域名下的請求都會被403禁止訪問。

 

 

3. 解決跨域

跨域是前端經常會遇到的問題,解決的方式有很多,例如:jsonp、node.js中轉、CORS等。

但是使用 Nginx 來跨域簡單明瞭,主要用到的是 Nginx 的反向代理原理。

參考代碼:

# 首尾配置暫時忽略
server {
        listen       8080;        
        server_name  localhost;

        location / {
            # 跨域代理設置
            proxy_pass http://www.proxy.com; # 要實現跨域的域名
            add_header Access-Control-Allow-Origin *;
            add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
            add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
        }
}
# 首尾配置暫時忽略
複製代碼

思路就是在反向代理請求過程中,增加可以跨域訪問的請求頭。不得不說這個方式真香,似乎幫我們前端打開了通往跨域的新大門~

 

4. 適配PC和移動端

我們在開發一些門戶或者對外網站的時候,經常要考慮使用移動端和PC端兩套頁面。因爲單純使用一個頁面來做自適應,有時候總是會有些捉襟見肘。

之前我們使用的方案多數是整兩個 domain,一個叫xxx.com,另一個叫m.xxx.com。亦或是搞兩套路由來進行區分,移動端所有路由前面都增加一個 path,如xxx.com/login,則對用移動端的路由就設成xxx.com/m/login

這兩種方式其實都存在一個問題—— PC 和移動端所有的 url 都不一樣,給用戶的體驗並不是太好。

最關鍵的是還需要處理一個邏輯,無論是每個移動端頁面,還是PC端頁面,在頁面開始渲染的時候都要再根據 navigator.userAgent,進行一次重定向。因爲要保證PC端和移動端的路由要能根據設備,互相進行跳轉。每個頁面都要處理這個,這顯得非常的多餘。

如果使用 Nginx 處理這個,就顯得再適合不過了。

參考代碼:

# 首尾配置暫時忽略
server {
        listen       8080;        
        server_name  localhost;

        location / {
            # 適配移動端/PC端配置
            set $type "pc";
            if ($http_user_agent ~* (mobile|nokia|iphone|ipad|android|samsung|htc|blackberry)) {
                set $type "mobile";
            }
            root /usr/local/var/www/my-project/$type; # 根據設備類型選擇設定根目錄文件夾名(pc/mobile)
            index  index.html index.htm;
        }
}
# 首尾配置暫時忽略
複製代碼

這個配置稍微多一點,主要思路也是通過判斷瀏覽器的 useragent 來取對應的靜態頁面資源。

如果我們的前端應用部署後是有服務的怎麼辦呢?那就不取對應的靜態頁面,而是 proxy_pass 代理到對應的頁面路由上即可。

 

5. Gzip 壓縮

這個功能基於 ngx_http_gzip_module 模塊,該模板是nginx內置的

日常開發中,我們經常遇到前端靜態資源比較大導致頁面響應變慢的問題。通常我們的做法是將靜態資源放入CDN服務中。

但是對於有些不適合接或者來不及接CDN的,我們就可以開啓 Nginx 的gzip功能,快速完成隊 html、css、js 等靜態資源的壓縮。要注意的是,圖片資源壓縮前後區別不大,gzip壓縮圖片還會白白消耗服務器資源,得不償失。

開啓 Nginx 的gzip功能,參考配置如下:

http {
    # 配置gzip壓縮
    gzip  on;
    gzip_min_length 1000; # 設定壓縮的臨界點
    gzip_comp_level 3; # 壓縮級別
    gzip_types      text/plain application/xml; # 要壓縮的文件類別
}
複製代碼

沒開啓 gzip 壓縮之前(該html是598kb):

 

 

開啓 gzip 壓縮後(該html是517kb):

 

 

 

 

如圖二中的紅框標識,能看到響應頭帶上了Content-Encoding: gzip 標識,就說明你配置的gzip壓縮功能起效果了。

 

6. 合併請求

從這個部分開始,需要使用 Nginx 第三方擴展模塊了,故需要使用編譯版的 Nginx(傳送門 Mac OS下安裝及配置nginx)。

web前端性能優化中很重要的一條就是減少 http 請求數。而通過淘寶開發的 nginx-http-concat 第三方模塊,我們可以實現多請求的合併。

配置好 Nginx 的合併請求功能後,前端就可以用一種特殊的 url 請求規則(例如example.com/??1.js,2.js,3.js )向 Nginx 發起請求。

此時,Nginx 會將前端想要的多個資源請求合併成一個請求返回給前端,極大的減少了網絡請求時間的開銷。

參考配置如下:

server {
    ......
    # 新增一個 location,static 爲靜態資源目錄
    location /static/ {
        concat on; # 是否打開資源合併開關
        concat_types application/javascript; # 允許合併的資源類型
        concat_unique off; # 是否允許合併不同類型的資源
        concat_max_files 20; # 允許合併的最大資源數目
    }
}

7. 圖片處理

需要第三方模塊 ngx_http_image_filter_module 支持

主要是可以幫助前端完成一些對圖片裁剪/縮放/旋轉/圖片品質等參數的調整。

參考配置如下:

 

 

Nginx 配置好這個模塊之後,你只需要訪問類似 http://127.0.0.1:8080/img/weiciyun.jpeg?w=100&h=100 這種url,就可以拿到你想要的圖片資源。針對是極大的豐富了我們的前端生產力。

8. 修改網頁內容

Nginx 內置了但是沒有默認啓用的 Module ngx_http_sub_module 模塊,能讓 Nginx 具備替換頁面代碼塊的能力。

參考配置如下:

location / {
    ......
    # 在 <body> 中插入一段 html 片段
    sub_filter '</body>' '<p>好嗨喲~我是插入的html片段</p></body>'
}
複製代碼

引入第三方模塊 nginx-http-footer-filter 後,可以實現直接向頁面底部插入代碼塊的能力。

 

 

 

Nginx 引入了這兩個模塊後直接給前端賦能,這給我們前端提供了無限的可能。比如:

  • 快速切換開發環境(將域名訪問替換掉ip訪問,實現不同環境的切換)
  • 移動頁面增加二維碼方便掃描訪問(增加頁面網址生成二維碼的js,手機掃一掃就能進入你的移動頁面)
  • js文件底部插入sourceMappingURL方便debug線上問題
  • ......

這個應用場景看起來應該是是最貼近前端開發,直接跟我們最熟悉的 html/js/css 打交道,這對我們前端來說有一種久違的熟悉感。非常推薦大家去試一試。

總結

Nginx 助力前端開發的場景應該遠遠不止本文中的8個,筆者這裏權當拋磚引玉,更多、更好的用法還在等着大家去探索和發現。

最後,有兩句話想送給大家——


作者:敲完代碼再睡覺
鏈接:https://juejin.im/post/5e9ab2e851882573a67f62a0
來源:掘金
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章