這標題我相信看到的人會有些黑人問號,但卻是我在做AC學期三期末考時碰到的一個小問題,還請容我緩緩道來。 如果只想看要怎麼讓node判別是否在Heroku上運行的解法可以拉到最後。
緣起
其中一個題目是短網址產生器,撰寫程式碼的過程沒什麼問題,基本的程式邏輯會是這個樣子。
使用者輸入網址->若在資料庫內已有資料->回應對應的短網址
使用者輸入網址->若在資料庫內沒有資料->將本地的位置+產生的urlCode存入資料庫->導向對應的endpoint->回傳給使用者。
舉個例子來說,當使用者輸入 https://www.youtube.com 時,會回傳類似
http://127.0.0.1/Y5ms8 的結果,這看起來沒什麼問題,但題目要求要同時部署到heroku上就會產生一個小麻煩了。原因很簡單,從上面這簡單的例子可以看出短網址的組成只有兩個部分
本地伺服器位置+產生的urlCode,也就是說今天搬到heroku上運行後,雖然不會報錯,但產出的網址還是會類似 http://127.0.0.1/Y5ms8 而非像是 https://arcane-tor-34628.herokuapp.com/Y5ms8 的東西,這下可就尷尬了。
問題解析
問題其實相當的單純,我們先看一下原始的程式碼是怎麼寫的
//將產生的urlCOde與baseUrl結合,此時的baseUrl為 "http://127.0.0.1:3000" const shortUrl = baseUrl + '/' + urlCode; //將產生的短網址等資訊存進資料庫 let url = new Url({ longUrl, shortUrl, urlCode, date: new Date() }); await url.save();
也就是說,當前的程式碼並沒有顧及到程式是在那裡運行的!它總是會回傳baseUrl + urlCode的組合,於是這就產生了兩種不同的思考方向去解決題目的要求。
方法一,暴力解法:直接做兩種版本,本地版本&Heroku版本
我知道方法一聽起來很~~~蠢,不過倒不失為一個最終手段,寫程式的前輩常常告訴我們先求有再求好,現在既然已經有個保險方案便可以放在心裡最為不得已的備案,英文有句話是這麼說的
“It’s like your fat pants,you are not gonna wear them,but you’re glad to know where they are."
用來形容這情況再合適不過了。
方法二:讓程式判別所使用的伺服器並產生對應的短網址
這種想法就合理得多了,基本上一模一樣的東西做兩份根本是討打嘛!
此解法中虛擬碼的邏輯大概會像以下這樣
if 我在heroku上運行 { const shortUrl = herokuUrl + '/' + urlCode } else { const shortUrl = baseUrl + '/' + urlCode }
那剩下的部分就只是要找出讓node知道怎麼判別運行環境這點即可!
解法:設置Heroku環境變數
過程中我嘗試了幾種不同的方式,最終覺得這個做法最為單純直觀。
如果是AC的學生,應該對設置環境變數不陌生,也就是利用process.env.變數名稱 來隱藏一些敏感資訊,heroku上自然也有類似的設定,你可以透過下方的指令設定環境變數在heroku上使用
heroku config:set
變數名稱 = 變數值
i.e
heroku config:set IsHeroku = true
console.log(process.env.IsHeroku) //true
藉由這樣的環境變數設置,由於僅在heroku上有用,本地端使用時將會辨識為undefined,了解到這些後便可以修改我們的程式碼囉!
//首先設定環境變數,在終端機輸入以下指令 heroku config:set HEROKU = true //修改對應的程式碼 let shortUrl; if (process.env.HEROKU) { shortUrl = herokuUrl + '/' + urlCode; } else { shortUrl = baseUrl + '/' + urlCode; }
結語
如何? 完全運用課程所學就解決了這個小問題~!比起做兩個版本的解法來說專業多了吧!
整個解題過程會再次發現虛擬碼確實有它的用處在,Stackoverflow中也不乏用虛擬碼進行提問的網友。重點還是在於徹底釐清自己的問題,理解自己目前的癥結點是程式邏輯還是語法工具的不足,這樣關鍵字也會比較好下,比方說當我知道我目前的癥結點後,我採用的關鍵字便是"node localhost heroku",很快的便找到與我有相同問題的網友並開啟了一連串的解法試驗,最終找到自己最滿意的做法。 很多時候你手中掌握的工具其實已經足夠了,你只是需要換個角度去看問題,網友提供的意見則能幫助你快速的從不同角度看待同一個問題,這也是寫程式的醍醐味~!
若你是AC的學生,相信這個做法能幫助你在期末作業時省下一些功夫:P 祝學習愉快!