
前一陣子用nginx分擔了我網站由tomcat處理的的http服務,本文就跟大家分享下我的實戰過程,以及如何從0開始用nginx來訪問你的前端項目,歡迎各位感興趣的開發者閱讀本文。
寫在前面我開源項目[1]的第三方登錄模塊用到了localStorage來獲取用戶的授權結果,前幾天有個網友反饋說他從我文章的鏈接中點進去沒法登錄。
經過一番排查后,我發現我在文章中留的鏈接是https://kaisir.cn/chat-system[2],而第三方鑒權回調設置的鏈接是https://www.kaisir.cn/chat-system[3]。由于我域名解析那里配置了@訪問與www訪問指向的都是同一個網站,因此兩者訪問界面相同。但是回調地址中有www,請求授權的訪問界面沒有www,出現了跨域問題。
跨域后,localStorage里的東西自然是不一樣的,因此就出現了這個網友所說的問題。
解決辦法既然兩者訪問的都是同一個服務器上的資源,那么我們就可以在服務端配置重定向,當請求的地址沒有攜帶www時,我們就給他重定向到帶www的地址。
于是我搜了一波使用tomcat配置未攜帶www的網站自動添加www,看了一眼方案,比較麻煩,不想折騰。
經過一番搜索后,我發現使用nginx解決這個問題比較簡單,于是我花了一點時間學了下nginx,完美解決了這個問題。
注意:本文不介紹如何安裝nginx,對此不了解的開發者,請移步nginx官網[4]進行學習。
移除tomcat的配置首先我們先把tomact已配置好的一些http服務移除掉,此處要刪除的有:http訪問跳轉https、域名證書、靜態資源。
注意:如果你沒有使用tomcat可以跳過此章節, 直接學習nginx的相關配置。
關閉https訪問,刪除域名證書
我們打開tomcat的conf目錄下的server.xml,找到Service標簽里port為80的Connector標簽,刪除標簽內的redirectPort屬性,如下圖所示。
注意:你還需要修改port的值,將其改為任意一個非80的值,因為nginx需要使用80端口號。
隨后,繼續找port為443的Connector標簽,將其刪除,如下圖所示。
最后,刪除你目錄下后綴為jks的域名文件即可。
打開tomcat的webapps目錄將你的靜態資源(前端項目)刪掉即可。
我們打開tomcat的conf目錄下的web.xml文件,找到login-config標簽和security-constraint的內容,將其刪除,如下所示:
<!--開啟http強制跳轉https訪問--><login-config><!--AuthorizationsettingforSSL--><auth-method>CLIENT-CERT</auth-method><realm-name>ClientCertUsers-onlyArea</realm-name></login-config><security-constraint><!--AuthorizationsettingforSSL--><web-resource-collection><web-resource-name>SSL</web-resource-name><url-pattern>/*</url-pattern></web-resource-collection><user-data-constraint><transport-guarantee>CONFIDENTIAL</transport-guarantee></user-data-constraint></security-constraint>配置nginx接下來,我們來配置nginx,讓它來全面接管客戶端的http請求,反向代理tomcat提供的服務,成功與tomcat完成配合。
配置虛擬主機首先,我們需要先把虛擬主機配置好,它的作用就是模塊化管理你的所有服務器資源,避免全部都一股腦的寫入nginx的主配置文件,從而導致的可維護性降低問題。
我們打開nginx的conf目錄,在其目錄下找到virtualhost.conf的文件(如果沒有則需要手動創建),該文件的作用就是將所有的服務器配置引入進來進行統一管理,打開文件后,我們寫入如下所示的內容:
#VirtualHostConfiguration.#默認存在的,如果不存在可以不理includevhosts/localhost.vhost;#我們新加的includevhosts/kaisir.cn;在上面的配置文件中,我們新加了一個kaisir.cn的配置,我們需要在vhosts目錄下創建這個文件,這個目錄也是在conf目錄中的(如果沒有就自己創建),我們直接創建這個文件即可。
注意:創建的文件不能包含后綴名,如果你有多個應用則在此處創建,然后在virtualhost.conf文件中使用include指令進行引入即可。
隨后,我們打開conf目錄下的nginx.conf文件,把剛才創建的virtualhost.conf文件引入進去,我們找到http標簽,在標簽內部添加如下所示的內容:
#...其他內容省略...http{#引入服務配置文件includevirtualhost.conf;}做完上述操作后,我們就可以愉快的編輯我們在vhosts目錄下創建的文件了。
服務器配置文件在上述配置中,我們在vhosts目錄下創建的文件就是我們的服務器配置文件了,http訪問的相關配置都是在此文件中進行寫入。
配置端口監聽我們打開前面創建的kaisir.cn文件,寫入如下所示的內容:
server{listen80;listen443ssl;}上述配置中:
server 為本文件的根指令,本章節后面所有的配置都是寫在這個這個指令里面的 listen 監聽80端口(即普通http的訪問) listen 監聽443端口以及ssl訪問(即https的訪問) 配置ssl證書我們寫入如下所示的代碼用來配置https訪問時所需的ssl證書文件:
#配置ssl證書ssl_certificate/Users/likai/nginx-website/conf/kaisir.cn/1_kaisir.cn_bundle.crt;ssl_certificate_key/Users/likai/nginx-website/conf/kaisir.cn/2_kaisir.cn.key;ssl_session_timeout5m;ssl_ciphersECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;ssl_protocolsTLSv1TLSv1.1TLSv1.2TLSv1.3;ssl_prefer_server_cipherson;上述配置中,我們主要修改2個部分的配置:
ssl_certificate 你域名的ssl證書文件位置(文件類型一定為crt格式的) ssl_certificate_key 你域名證書所對應的密鑰文件 (文件類型一定為key格式的)注意:ssl證書需要去你域名的注冊商那里下載
配置網站訪問路徑接下來,我們來配置下每個訪問路徑所指向的靜態資源(前端項目),我們會用location指令來配置一條路徑的訪問,如下所示,我們配置了域名的根目錄指向(即/的含義),指令內部分別指定了靜態資源在硬盤中的路徑以及默認的首頁文件。
#根路徑location/{#項目路徑root/Users/likai/nginx-website/kasir.cn;#默認首頁文件indexindex.htmlindex.htm;}配置完根目錄后,我們再來看下子目錄的相關訪問配置,如下所示:
location/chat-system{#項目路徑alias/Users/likai/nginx-website/chat-system/;#默認首頁文件indexindex.htmlindex.htm;#解決網頁刷新404try_files$uri$uri//chat-system/index.html;}通過觀察上述配置后,我們發現的不同點如下:
alias 配置子目錄時,我們使用了alias來指向項目 try_files 這里是解決vue項目啟用history模式后,網頁刷新404問題注意:如果你的vue項目是用Vue CLI搭建的,那么就需要修改vue.config.js中的publicPath屬性值為:process.env.NODE_ENV === "development" ? "./" : "/chat-system"。"/chat-system"即為生產環境的訪問路徑,就是我們剛才在location指令行所配置的。如果此處配置錯誤的話,你打包后的vue項目在瀏覽器訪問將使一片空白??
最后,在路由配置文件中,傳入參數:createWebHistory(process.env.BASE_URL)。
具體代碼請移步提交記錄:build: 啟用路由的history模式[5]
自定義錯誤頁在瀏覽器訪問一個不存在的頁面或者服務器內部發生錯誤時,我們可能需要對其進行處理,此時我們就需要用到error_page指令,如下所示:
#自定義404與500頁面,指向下面的locationerror_page404500/404.html;#自定義404頁面location/404.html{alias/Users/likai/nginx-website/404-page/;#默認首頁文件indexindex.htmlindex.htm;}注意:配置了error_page后,一定要配置location來指向你要訪問的靜態項目。
反向代理tomcat提供的服務我們需要在location指令內部使用proxy_pass來代理tomcat提供的服務,配置如下所示:
#反向代理Java接口,多路徑采用正則表達式匹配location~^/(api|uploads|download|other)/{proxy_passhttp://127.0.0.1:8080;proxy_set_headerHost$host;proxy_set_headerX-Real-IP$remote_addr;proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for;}注意:location指令中使用正則進行了接口前綴地址的匹配,此處匹配的是/api/*、/uploads/*、/download/*、/other/*
如果你的tomcat還提供了websocket服務,那么還需要單獨配一條location指令,用來代理,配置如下所示:
#反向代理websocket請求location/websocket{proxy_passhttp://127.0.0.1:8080/websocket/;proxy_http_version1.1;proxy_set_headerUpgrade$http_upgrade;proxy_set_headerConnection"upgrade";}如果你沒有使用Java來做服務端,而是使用python、php、c#等語言做的,也可以使用proxy_pass來做反向代理。
重定向未攜帶www的請求最后,我們來解決下本文開頭所說的問題,在nginx中解決這個問題非常簡單,我們只需要判斷下請求地址中是否包含www即可,如果不包含則301重定向到帶www的地址即可,配置如下所示:
#主機名稱,哪個寫在前面,默認就跳轉哪個server_namewww.kaisir.cnkaisir.cn;#請求網址中不包含www,則重定向到攜帶www的https地址if($http_host!~"^www.kaisir.cn$"){return301https://$server_name$request_uri;}配置完成后,我們打開瀏覽器訪問kaisir.cn[6]來驗證下是否達到了我們的預期,如下圖所示,完美解決??
注意:上述配置中,我們使用正則表達式對url進行了一波匹配,其中server_name指令的作用是如果訪問地址中包含此處所寫的東西,就會觸發執行這里的配置。
此配置還會將你的http請求默認重定向到https。
完整的配置文件本章節完整的配置文件內容如下所示:
server{listen80;listen443ssl;#主機名稱,哪個寫在前面,默認就跳轉哪個server_namewww.kaisir.cnkaisir.cn;#請求網址中不包含www,則重定向到攜帶www的https地址if($http_host!~"^www.kaisir.cn$"){return301https://$server_name$request_uri;}error_page497https://$server_name$request_uri;#自定義404與500頁面,指向下面的locationerror_page404500/404.html;#配置ssl證書ssl_certificate/Users/likai/nginx-website/conf/kaisir.cn/1_kaisir.cn_bundle.crt;ssl_certificate_key/Users/likai/nginx-website/conf/kaisir.cn/2_kaisir.cn.key;ssl_session_timeout5m;ssl_ciphersECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;ssl_protocolsTLSv1TLSv1.1TLSv1.2TLSv1.3;ssl_prefer_server_cipherson;#引用虛擬配置文件includevhosts/_nginx.vhost.fpm;#根路徑location/{#項目路徑root/Users/likai/nginx-website/kasir.cn;#默認首頁文件indexindex.htmlindex.htm;}location/chat-system{#項目路徑alias/Users/likai/nginx-website/chat-system/;#默認首頁文件indexindex.htmlindex.htm;#解決網頁刷新404try_files$uri$uri//chat-system/index.html;}#自定義404頁面location/404.html{alias/Users/likai/nginx-website/404-page/;#默認首頁文件indexindex.htmlindex.htm;}#反向代理Java接口,多路徑采用正則表達式匹配location~^/(api|uploads|download|other)/{proxy_passhttp://127.0.0.1:8080;proxy_set_headerHost$host;proxy_set_headerX-Real-IP$remote_addr;proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for;}#反向代理websocket請求location/websocket{proxy_passhttp://127.0.0.1:8080/websocket/;proxy_http_version1.1;proxy_set_headerUpgrade$http_upgrade;proxy_set_headerConnection"upgrade";}}nginx配置文件接下來,我們來看下nginx的配置文件,做一些小優化。本章節的所有配置都是在nginx.conf文件中完成,本章節提到的所有配置文件均指nginx.conf。
最大連接數最大連接數也可以成為并發數,即同一時刻最多支持多少個客戶端接入,在配置文件中加入如下所示的配置:
events{#允許的連接數worker_connections20000;}開啟gzipgzip壓縮可以節省我們的帶寬資源,提升網站的加載速度。它的開啟方式也很簡單,在配置文件的http指令內添加,如下所示:
http{#開啟gzipgzipon;#允許壓縮的最小字節數gzip_min_length10;#IE瀏覽器1-6版本禁用gzipgzip_disable"MSIE[1-6].";#啟用gzip的文件類型gzip_typestext/plainapplication/x-javascripttext/csstext/javascriptapplication/xml;}配置日志日志可以用來記錄每個客戶端的訪問時間、ip、瀏覽器等信息,對我們后續的網站維護帶來幫助,在配置文件的http指令內添加如下所示的配置:
#設置日志格式,添加客戶端真實ip等信息formatchatSystemLogFormat'$http_xforwarded_for-$remote_user[$time_local]''"$request"$status$body_bytes_sent''"$http_referer""$http_user_agent"';#訪問日志文件存放路徑ss_log/Users/likai/nginx-website/logs-chat-system/access.logchatSystemLogFormatbuffer=32k;配置文件上傳大小如果你的網站提供了文件上傳服務,那么文件的大小限制除了在你的服務端項目中配置外,還需要在nginx中配置。
同樣的,在配置文件的http指令內添加如下所示的配置:
#客戶端可以上傳的文件大小client_max_body_size100m;完整的配置文件完整的配置如下所示:
userlikaistaff;worker_processes8;error_log/Applications/MxSrvs/logs/errors_nginx.log;#error_loglogs/error.lognotice;#error_loglogs/error.loginfo;#pidlogs/nginx.pid;events{#允許的連接數worker_connections20000;}http{#gzip匹配類型配置文件includemime.types;default_typeapplication/octet-stream;#客戶端可以上傳的文件大小client_max_body_size100m;#開啟gzipgzipon;#允許壓縮的最小字節數gzip_min_length10;#IE瀏覽器1-6版本禁用gzipgzip_disable"MSIE[1-6].";#啟用gzip的文件類型gzip_typestext/plainapplication/x-javascripttext/csstext/javascriptapplication/xml;#設置日志格式,添加客戶端真實ip等信息log_formatchatSystemLogFormat'$http_xforwarded_for-$remote_user[$time_local]''"$request"$status$body_bytes_sent''"$http_referer""$http_user_agent"';#訪問日志文件存放路徑access_log/Users/likai/nginx-website/logs-chat-system/access.logchatSystemLogFormatbuffer=32k;#引入服務配置文件includevirtualhost.conf;sendfileon;keepalive_timeout65;}參考資料[1]開源項目: https://kaisir.cn/chat-system
[2]https://kaisir.cn/chat-system: https://kaisir.cn/chat-system
[3]https://www.kaisir.cn/chat-system: https://www.kaisir.cn/chat-system
[4]nginx官網: https://www.nginx.com/resources/wiki/start/topics/tutorials/install/
[5]build: 啟用路由的history模式: https://github.com/likaia/chat-system/commit/e7c55a714f2610a87a5c87d5864bc4c342a298b0
[6]kaisir.cn: http://kaisir.cn
[7]個人網站: https://www.kaisir.cn/
聲明:本文僅為傳遞更多網絡信息,不代表IT資訊網觀點和意見,僅供參考了解,更不能作為投資使用依據。