2013-03-11 79 views
1

我打算在下一個項目中使用Laravel框架。 現在我被困在組織鏈接靜態內容在我的項目(圖片,腳本等) 例如,我有這個緩存選項(不緩存所有的靜態文件,nginx的):在Laravel中使用HTTP緩存,生成靜態文件路徑

location ~* \.(jpg|jpeg|gif|css|png|js|ico|html)$ { 
    expires max; 
} 

哪有我建立一個鏈接到文件main.js? 如何判斷文件是否過期?

在我目前的項目中,我有使用文件修改時間爲文件生成唯一前綴的版本控制系統。所以鏈接就像http://site.com/22566223435/js/main.js而下一次文件更改鏈接自動更改。

Laravel實現此功能的最佳做法是什麼?謝謝!

+0

你可能想看看https://github.com/TheMonkeys/laravel-cachebuster – mpen 2014-03-23 19:25:38

回答

5

我會這樣做的查詢字符串,它很容易,足夠準確,並不需要任何複雜的圖層來實現。只需將文件的最後修改作爲查詢字符串放在其鏈接上即可。這將強制瀏覽器刷新文件。

<link rel="stylesheet" type="text/css" href="/css/style.min.css?v=<?= File::modified(path('public').'/css/style.min.css') ?>" /> 

爲了簡化這一點,您可以創建一個簡單的類來生成文件鏈接並緩存上次修改以提高性能。如果使用LESS編譯器,也可以使用自定義函數實現。

現在,關於服務器緩存,如果您的應用程序讓很多用戶真正從中受益,那麼您應該考慮CDN,它也處理全球分佈,並且可以很好地處理該查詢字符串系統。

編輯:

也有可能接近與的RewriteRules在Apache(沒有與任何nginx的經驗,幫助上壽)。用於生成查詢字符串的相同技術,可以用來爲URI生成前綴(或後綴)。

你可以嘗試的另一件事是定義一個子域主要用於處理像assets.example.com這樣的靜態資產。這個域可以完全由沒有Laravel棧的web服務器處理。但是,這取決於您的資產在您的項目中的開發,編譯和使用情況。

我們的方法:

在我們公司,我們使用CloudFront的和S3的數據庫實體資產。每個實體都有它自己的S3目錄,每個資產都通過一個唯一的文件名(由md5生成,避免重新上傳的資產重複)進行版本控制。喜歡的東西:

/posts/876/060b90d67ac0c5e24da6de6ae547e3b1.jpg 

我們還定義了我們的CloudFront的10子域,所以瀏覽器不達到相同的域6-8的併發請求的限制:

cdn0.example.com 
cdn1.example.com 
cdn2.example.com 
... and so on 

在我們的數據庫中的每個條目使用通過計算resource.id % 10挑選出的獨佔子域,這非常快速並且始終爲每個實體返回相同的子域(幫助客戶端和CloudFront緩存)。這是您可以爲圖片提供最好的服務。

UI圖像存儲在一個獨家子域assets.example.com,而那些沒有到目前爲止版本,因爲我們不改變設計那麼多,如果我們這樣做,我們可能會提出新的資產裏面的東西像/v2//newthemename/夾。這種方法有助於回滾,甚至用戶選擇的主題。

CSS和JS由Apache從Laravel /public目錄中提供。這不是最快的方法,但是由於我們現在專注於開發,所以自動編譯LESS和Closure更重要。當我們爲最終用戶啓動時,我們可能會想到一個自動化的部署系統,它可以編譯資產,使用時間戳前綴在S3/CloudFront上發佈它們,並緩存它們上次的視圖渲染時間戳。

+0

它看起來像一個很好的解決方案,但不是最好的,因爲查詢字符串參數被大多數代理剝奪。永遠不要我會嘗試它,謝謝! – Stanislav 2013-03-12 07:34:19

+0

我會編輯我的答案,並提供更多關於如何解決問題的建議。 – vFragosop 2013-03-12 13:02:08