“誰說前端需要懂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
來源:掘金
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。