這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
本來計劃至少一周總結一次學到的東西,不過好像沒有實現啊
一看時間都4月1號了,一個月了,總該寫點啥
最近運氣不好,出了很多事情,雖然都是不足為外人道的東西,但確實影響心情,希望大家每天都能開開心心的
今天寫一下前幾天遇到的一個需求:通過一個URL擷取使用者資訊的zip檔案
不涉及過多業務內容的話,就是要寫一個小Demo,通過一個給定URL,擷取一個zip檔案
實現一個極簡單的URL處理路由
既然是寫Demo,那麼肯定路由就Golang最簡單的ListenAndServe就好了
func main() { http.HandleFunc("/zipdownload", zipHandler) log.Println("Listening...") http.ListenAndServe(":9999", nil)}
完成zipHandler函數
按照Golang的Handler函數簽名邀請,完成zipHandler函數
func zipHandler(rw http.ResponseWriter, r *http.Request) { zipName := "ZipTest.zip" rw.Header().Set("Content-Type", "application/zip") rw.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", zipName)) err := getZip(rw) if err != nil { log.Fatal(err) }}
設定回應標頭資訊
rw.Header().Set("Content-Type", "application/zip")
設定response的頭資訊中的檔案類型,對於zip檔案,一般可以設定為application/zip
或application/octet-stream
更具體的說明,可以在Complete list of MIME types獲得,我是選擇了application/zip
來告訴伺服器精確的檔案類型
rw.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", zipName))
設定Content-Disposition
為attachment
即附件類型,同時設定附件檔案名稱為我們給定的zipName
回應標頭資訊中的Content-Disposition
用於告知瀏覽器其擷取到的檔案是需要展示與頁面內還是需要作為附件儲存到使用者本地,如果需要展示在頁面內,設定為inline
,否則設定為attachemnt
,在設定為attachment
時還可以額外規定該附件的檔案名稱,更具體的說明,可以在Content-Disposition獲得
完成這兩句代碼後,功能其實已經完成了一大半了,最初我就是被這個地方卡住了,在獲得需求時思想泡裡充滿了怎麼樣才能讓HTTP響應得到一個zip檔案並且讓瀏覽器將這個檔案下載下來而不是試圖展示出來
的問題
完成getZip函數
這裡我們只需要完成一個比較基礎的zip流程就好,就像我上面說的,這個需求,最難的其實是上面對HTTP Response中Header資訊的瞭解
func getZip(w io.Writer) error { zipW := zip.NewWriter(w) defer zipW.Close() for i := 0; i < 5; i++ { f, err := zipW.Create(strconv.Itoa(i) + ".txt") if err != nil { return err } _, err = f.Write([]byte(fmt.Sprintf("Hello file %d", i))) if err != nil { return err } } return nil}
建立zip.Writer
zipW := zip.NewWriter(w)
該方法建立一個zip.Writer
,用於向zip檔案中寫入內容,即打包的檔案
參數為io.Writer
,那麼我們這裡當然就是使用http.ResponseWriter
傳回值為一個zip.Writer
,最後的zip內容都會寫入這個zip.Writer
,而最終當然是寫入了參數的io.Writer
中,也就是我們的http.ResponseWriter
中
記得defer zipW.Close()
關閉zip.Writer
向zip.Writer中寫入檔案
f, err := zipW.Create(strconv.Itoa(i) + ".txt")
該方法向zip.Writer
中添加一個檔案,也就是說向zip檔案中添加一個檔案
參數字為字串,會作為寫入zip中的檔案的檔案名稱
第一個傳回值為一個io.Writer
,用於向其中,也就是向我們添加到zip的檔案中,寫入檔案內容,即如_, err = f.Write([]byte(fmt.Sprintf("Hello file %d", i)))
代碼所示,我們向檔案中寫入了簡單的字串
運行程式
接下來,只需要在程式main.go
所在目錄運行go run main.go
就可以在你的瀏覽器訪問localhost:9999/zipdownload
了,瀏覽器會下載一個zip檔案
下載的ZipTest及解壓後的內容
最後,代碼已經上傳到了我的Github倉庫可以直接下載測試
最最後,上一篇文章的時候我吐槽了下簡書總是不讓我貼了外鏈圖片等文章發布,今天又試了下,居然沒這個問題了,比如這個文章裡的圖片就是外鏈的,開心
最最最後,當然還是歡迎訪問我的個人部落格