開篇先來聊一聊縮略圖吧,其經(jīng)典應(yīng)用場景就是商品列表、詳情以及查看大圖時返回不同尺寸的圖片。好處,額,閉上眼睛自己體會。我看到過一些做法是在圖片保存時就生成三套縮略圖提供給前端訪問,這樣其實是可以滿足基本需求的,只是局限比較大,譬如下面這幾種情況:
1、系統(tǒng)初期是基于pc做的開發(fā),生成的縮略圖也是提供給pc端使用。某個月黑風(fēng)高的夜晚,領(lǐng)導(dǎo)突然拉著你的小手說我們明天開始做移動端,并且移動端的需要的圖片尺寸和pc端不一樣。
2、換領(lǐng)導(dǎo)了,新來的領(lǐng)導(dǎo)說列表頁為什么加載這么慢,把寬320px的圖片換成319px的,以前的數(shù)據(jù)全部要換~換~換~。
關(guān)于生成縮略圖的思考
為了技(yi)術(shù)(lao)創(chuàng)(yong)新(yi),我們重新設(shè)計了縮略圖的生成方式,與其生成固定不可更改的縮略圖,不如根據(jù)前端的需(bian)求(hua)來生成縮略圖,這樣無論前端是需要什么尺寸我們都可以輕松應(yīng)對。至于安全性,我們可以在后端配置允許訪問的尺寸集合,遇到非法的請求,直接給他一張小黃圖就好。于是我們的圖片訪問流程大概變成了這個樣子:
1、用戶發(fā)起圖片請求,服務(wù)端拿到請求,檢查圖片是否存在,不存在則返回小黃圖。
2、驗證圖片請求是否帶有尺寸參數(shù),沒有則返回原圖,尺寸超過原圖也直接返回原圖。
3、如果帶有尺寸參數(shù),驗證是否在服務(wù)器允許的參數(shù)范圍內(nèi),不在則返回小黃圖。
4、判斷該尺寸的縮略圖是否存在,不存在則生成縮略圖,存在即直接返回縮略圖。
縮略圖只會在第一次訪問時生成,總體來說不會太影響圖片訪問速度。思路大概就是這個樣子,接下來就只需要從服務(wù)端拿到用戶的圖片請求并處理。
關(guān)于圖片請求url的思考
平時我們訪問圖片的方式大概是這個樣子,http://xx.com/xx.png,那么帶參數(shù)的圖片請求會是個什么樣子呢,我想最好像這樣吧:http://xx.com/xx.png?width=320。
后端如何拿到這個請求的參數(shù)并控制其返回的內(nèi)容。我能想到的有兩個辦法:
1、將圖片訪問集中到一個webapi接口,將圖片路徑和尺寸當(dāng)做參數(shù)傳過來統(tǒng)一處理,webapi接口以流的形式返回圖片。
2、是否可以將特定的圖片請求使用一個自定義的IHttpHandler來處理。
其實仔細(xì)一想,第一個辦法實現(xiàn)起來并不是那么優(yōu)雅,并且也不能達(dá)到我們http://xx.com/xx.png?width=320的需求,甚至圖片返回的速度也會變慢不少,那么我們來分析第二個辦法的可行性。我的圖片都是存儲在/upload/image/這個目錄之下,那么前端的圖片訪問也必然是http://file.com/upload/image/xx.png,我們只需要將帶/upload/image/的請求映射到我們自定義的IHttpHandler來處理即可。
解決方案
1、自定義HttpHandler:
using System.Drawing;using System.Web;using cczcrv.Web.File.Uploader.Image;using System.IO;namespace cczcrv.Web.File.Filters { public class GetImageHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { //圖片不存在,返回默認(rèn)圖片 &n