1. 程式人生 > >靜態文件cdn自解析生成相對路徑

靜態文件cdn自解析生成相對路徑

.com 直接 失敗 目的 外文 進行 獲得 訪問 及其

一、場景和目標:
用戶上傳一個包含 index.html 的靜態資源壓縮包,資源內所有文件都是相互依賴的,不需要用戶對內部文件內容做任何特殊處理,僅通過服務端邏輯處理達到用戶訪問 http://xxx.xxx/guid/index.html 時就可以得到這個資源的所有數據並正常瀏覽。


二、技術:
nodejs、express
npm 包:decompress、request、crypto、pinyin


三、思路:
a、上傳解析:
對每一個資源生成唯一的 guid,將用戶上傳的壓縮包解壓之後,按照解壓完成的文件的目錄結構以 guid 為初始前綴拼接路徑,這樣就可以保證所有文件在 cdn 的相對路徑就是文件在原始資源包中的相對路徑,然後對文件信息和路徑進行存儲即可,在這中間的關鍵一步是要將靜態資源的 index.html 文件以其唯一 guid 為基礎存儲在 views 文件夾中。

b、訪問index:
用戶首先要獲得靜態資源的列表,其實就是獲得所有靜態資源的 guid 列表,或者說是靜態資源的唯一 id,這個唯一 id 都會對應一個唯一的 guid,當用戶訪問 [http://xxx.xxx/:id/ | http://xxx.xxx/:id/index | http://xxx.xxx/:id/index.html] 這些路徑時,配置中間件,通過 id 處理中間件去服務端獲取此 id 對應的 guid 值,然後將 views 中對應的 guid index文件直接 render 給用戶即可。
c、獲取相對路徑資源:
當瀏覽器拿到 index 文件之後,index 文件中的所有依賴都會以 index 文件的前置路徑為基準進行獲取,也就是說如果現在依賴一個 index.js 文件,這個文件相對於 index.html 文件的路徑是/scripts/index.js,那麽服務端就會收到一個請求,這個請求的 url 是 http://xxx.xxx/:id/scripts/index.js,這裏為了保證請求的正確性,並沒有在 index 文件 guid 解析完成之後向 cookie 中存儲 guid,而是所有靜態資源的請求都去獲取新的 guid 值,拿到 guid 之後,就可以通過相對路徑拼合出此靜態文件在 cdn 中存儲的位置路徑信息,路徑信息拼合好之後,使用 request 包的 pipe 方法直接相應給用戶 cdn 中靜態資源的數據即可。
通過上面三個步驟,就可以實現上面場景中所描述的要求,是此類問題的一種處理方式。


四、遇到的問題:
a、數據存儲
由於項目是以靜態資源為主的,因此要求服務端部分要輕量,因此在服務端處理邏輯中未加入任何數據庫、公有配置、權限、登陸等功能,所有的數據交互全部通過主項目的對外接口進行接入,保證了項目中服務端部分只有純邏輯,代碼量也比較少,是一種不錯的選擇。
b、確定所有目標文件位置
在這裏遇到一個問題就是,如果用戶上傳的壓縮包中存在一些不合法的或者不需要使用的額外文件怎麽辦,理論來說在服務端無法確定哪些文件是需要被引用的,但是根據上傳規定和要求,資源包內最外層一定要有一個 index.html 文件,那麽就可以通過 index 文件進行處理,只保留和 index 同層及其下層的文件,這樣可以保證 index 文件一定是在最外層的,其余文件全部忽略,保證只存儲有用的資源。

c、三方npm包解壓壓縮包時中文問題
剛開始使用的一個 npm 包解壓之後中文是亂碼,上傳 cdn 後找不到此文件,後面對亂碼文件的路徑進行 encode,然後可以在 cdn找到此文件了,但是再向用戶 pipe 時出現問題,被 encode 的文件無法 pipe,雖然文件請求返回了200,但是資源數據就是拿不到,很惆悵,在嘗試了五六個包之後,終於找到一個可以對中文進行正常解壓的包,算是先解決了亂碼問題,可encode 後無法向用戶 pipe 的問題還是沒有解決,於是想到了下面的方式。
d、阿裏雲cdn向用戶pipe文件時被encode的文件回傳失敗
由於 encode 的文件回傳失敗,直接存儲中文也不是很好,因此想到將中文轉換為拼音的辦法,就是在讀取資源包中的文件並拼合其 cdn 路徑時,對路徑中的中文進行轉換,轉為拼音,然後用戶訪問這些文件時對訪問的 url 也進行拼音轉換,這樣就確保了數據的正確性同時也避免在數據庫和 cdn 中存儲中文導致的各種問題。


五、流程圖:

技術分享圖片

六、示例:
假設現在上傳了個資源包,解壓後目錄結構長下面這個樣子:

/yyy
  /zzz
    zzz.html
/xxx
  index.html
  /js
    index.js
  /css
    index.css
  /images
    index.png

生成的 guid 長後面這個樣子:abcdefghijklmnopqrstuvwzyx。
那麽這些資源的 cdn 地址就是下面的樣子:

/abcdefghijklmnopqrstuvwzyx/index.html
/abcdefghijklmnopqrstuvwzyx/js/index.js
/abcdefghijklmnopqrstuvwzyx/css/index.css
/abcdefghijklmnopqrstuvwzyx/images/index.png

在 views 中將會存在一個名為abcdefghijklmnopqrstuvwzyx的文件夾,裏面靜靜的躺著 index.html 文件等待被用戶訪問。

七、結束。

靜態文件cdn自解析生成相對路徑