Go 項目實戰(zhàn):實現(xiàn)一個提供壓縮文件下載功能的 http server
最近遇到了一個下載靜態(tài)html報表的需求,需要以提供壓縮包的形式完成下載功能,實現(xiàn)的過程中發(fā)現(xiàn)相關文檔非常雜,故總結一下自己的實現(xiàn)。
開發(fā)環(huán)境:
系統(tǒng)環(huán)境:MacOS + Chrome 框架:beego 壓縮功能:tar + gzip 目標壓縮文件:自帶數(shù)據(jù)和全部包的靜態(tài)html文件
首先先提一下http server文件下載的實現(xiàn),其實就是在后端返回前端的數(shù)據(jù)包中,將數(shù)據(jù)頭設置為下載文件的格式,這樣前端收到返回的響應時,會直接觸發(fā)下載功能(就像時平時我們在chrome中點擊下載那樣)
數(shù)據(jù)頭設置格式如下:
func?(c?*Controller)Download()?{
????//...文件信息的產生邏輯
????//
????//rw為responseWriter
????rw?:=?c.Ctx.ResponseWriter
????//規(guī)定下載后的文件名
????rw.Header().Set("Content-Disposition",?"attachment;?filename="+"(文件名字)")
????rw.Header().Set("Content-Description",?"File?Transfer")
????//標明傳輸文件類型
????//如果是其他類型,請參照:https://www.runoob.com/http/http-content-type.html
????rw.Header().Set("Content-Type",?"application/octet-stream")
????rw.Header().Set("Content-Transfer-Encoding",?"binary")
????rw.Header().Set("Expires",?"0")
????rw.Header().Set("Cache-Control",?"must-revalidate")
????rw.Header().Set("Pragma",?"public")
????rw.WriteHeader(http.StatusOK)
????//文件的傳輸是用byte slice類型,本例子中:b是一個bytes.Buffer,則需調用b.Bytes()
????http.ServeContent(rw,?c.Ctx.Request,?"(文件名字)",?time.Now(),?bytes.NewReader(b.Bytes()))
}
這樣,beego后端就會將在頭部標記為下載文件的數(shù)據(jù)包發(fā)送給前端,前端收到后會自動啟動下載功能。
然而這只是最后一步的情況,如何將我們的文件先進行壓縮再發(fā)送給前端提供下載呢?
如果需要下載的不只一個文件,需要用tar打包,再用gzip進行壓縮,實現(xiàn)如下:
//最內層用bytes.Buffer來進行文件的存儲
var?b?bytes.Buffer
//嵌套tar包的writter和gzip包的writer
gw?:=?gzip.NewWriter(&b)
tw?:=?tar.NewWriter(gw)
dataFile?:=?//...文件的產生邏輯,dataFile為File類型
info,?_?:=?dataFile.Stat()
header,?_?:=?tar.FileInfoHeader(info,?"")
//下載后當前文件的路徑設置
header.Name?=?"report"?+?"/"?+?header.Name
err?:=?tw.WriteHeader(header)
if?err?!=?nil?{
??utils.LogErrorln(err.Error())
??return
}
_,?err?=?io.Copy(tw,?dataFile)
if?err?!=?nil?{
??utils.LogErrorln(err.Error())
}
//...可以繼續(xù)添加文件
//tar?writer?和?gzip?writer的關閉順序一定不能反
tw.Close()
gw.Close()
最后和中間步驟完成了,我們只剩File文件的產生邏輯了,由于是靜態(tài)html文件,我們需要把所有html引用的依賴包全部完整的寫入到生成的文件中的
原文作者:Hoofffman
原文鏈接:https://segmentfault.com/a/1190000038867527
推薦閱讀
評論
圖片
表情
