最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

?Go?語言實(shí)現(xiàn)?HTTP?文件上傳和下載

 更新時間:2022年09月06日 10:16:43   作者:小二上酒8  
這篇文章主要介紹了Go語言實(shí)現(xiàn)HTTP文件上傳和下載,文章圍繞主題展開詳細(xì)的內(nèi)容戒殺,具有一定的參考價值,需要的小伙伴可以參考一下

前言:

近我使用 Go 語言完成了一個正式的 Web 應(yīng)用,有一些方面的問題在使用 Go 開發(fā) Web 應(yīng)用過程中比較重要。過去,我將 Web 開發(fā)作為一項(xiàng)職業(yè)并且把使用不同的語言和范式開發(fā) Web 應(yīng)用作為一項(xiàng)愛好,因此對于 Web 開發(fā)領(lǐng)域有一些心得體會。

總的來說,我喜歡使用 Go 語言進(jìn)行 Web 開發(fā),盡管開始一段時間需要去適應(yīng)它。Go 語言有一些坑,但是正如本篇文章中所要討論的文件上傳與下載,Go 語言的標(biāo)準(zhǔn)庫與內(nèi)置函數(shù),使得開發(fā)是種愉快的體驗(yàn)。

在接下來的幾篇文章中,我將重點(diǎn)討論我在 Go 中編寫生產(chǎn)級 Web 應(yīng)用程序時遇到的一些問題,特別是關(guān)于身份驗(yàn)證/授權(quán)的問題。

這篇文章將展示 HTTP 文件上傳和下載的基本示例。我們將一個有 type 文本框和一個 uploadFile 上傳框的 HTML 表單作為客戶端。

讓我們來看下 Go 語言中是如何解決這種在 Web 開發(fā)中隨處可見的問題的。

代碼示例 首先,我們在服務(wù)器端設(shè)定兩個路由, /upload 用于文件上傳, /files/* 用于文件下載。

const maxUploadSize = 2 * 1024 * 2014 // 2 MB
const uploadPath = "./tmp"

func main() {
http.HandleFunc("/upload", uploadFileHandler())

fs := http.FileServer(http.Dir(uploadPath))
http.Handle("/files/", http.StripPrefix("/files", fs))

log.Print("Server started on localhost:8080, use /upload for uploading files and /files/{fileName} for downloading files.")
log.Fatal(http.ListenAndServe(":8080", nil))
}

我們還將要上傳的目標(biāo)目錄,以及我們接受的最大文件大小定義為常量。注意這里,整個文件服務(wù)的概念是如此的簡單 —— 我們僅使用標(biāo)準(zhǔn)庫中的工具,使用 http.FileServe 創(chuàng)建一個 HTTP 處理程序,它將使用 http.Dir(uploadPath) 提供的目錄來上傳文件。

現(xiàn)在我們只需要實(shí)現(xiàn) uploadFileHandler 。

這個處理程序?qū)韵鹿δ埽?/strong>

  • 驗(yàn)證文件最大值
  • 從請求驗(yàn)證文件和 POST 參數(shù)
  • 檢查所提供的文件類型(我們只接受圖像和 PDF)
  • 創(chuàng)建一個隨機(jī)文件名
  • 將文件寫入硬盤
  • 處理所有錯誤,如果一切順利返回成功消息

第一步,我們定義處理程序:

func uploadFileHandler() http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

然后,我們使用 http.MaxBytesReader 驗(yàn)證文件大小,當(dāng)文件大小大于設(shè)定值時它將返回一個錯誤。錯誤將被一個助手程序 renderError 進(jìn)行處理,它返回錯誤信息及對應(yīng)的 HTTP 狀態(tài)碼。

r.Body = http.MaxBytesReader(w, r.Body, maxUploadSize)
if err := r.ParseMultipartForm(maxUploadSize); err != nil {
renderError(w, "FILE_TOO_BIG", http.StatusBadRequest)
return
}

如果文件大小驗(yàn)證通過,我們將檢查并解析表單參數(shù)類型和上傳的文件,并讀取文件。在本例中,為了清晰起見,我們不使用花哨的 io.Reader 和 io.Writer 接口,我們只是簡單的將文件讀取到一個字節(jié)數(shù)組中,這點(diǎn)我們后面會寫到。

fileType := r.PostFormValue("type")
file, _, err := r.FormFile("uploadFile")
if err != nil {
renderError(w, "INVALID_FILE", http.StatusBadRequest)
return
}
defer file.Close()
fileBytes, err := ioutil.ReadAll(file)
if err != nil {
renderError(w, "INVALID_FILE", http.StatusBadRequest)
return
}

現(xiàn)在我們成功的驗(yàn)證了文件的大小,并且讀取了文件,接下來我們該檢驗(yàn)文件的類型了。一種廉價但是并不安全的方式,只檢查文件擴(kuò)展名,并相信用戶沒有改變它,但是對于一個正式的項(xiàng)目來講不應(yīng)該這么做。

幸運(yùn)的是,Go 標(biāo)準(zhǔn)庫提供給我們一個 http.DetectContentType 函數(shù),這個函數(shù)基于 mimesniff 算法,只需要讀取文件的前 512 個字節(jié)就能夠判定文件類型。

filetype := http.DetectContentType(fileBytes)
if filetype != "image/jpeg" && filetype != "image/jpg" &&
filetype != "image/gif" && filetype != "image/png" &&
filetype != "application/pdf" {
renderError(w, "INVALID_FILE_TYPE", http.StatusBadRequest)
return
}

在實(shí)際應(yīng)用程序中,我們可能會使用文件元數(shù)據(jù)做一些事情,例如將其保存到數(shù)據(jù)庫或?qū)⑵渫扑偷酵獠糠?wù)——以任何方式,我們將解析和操作元數(shù)據(jù)。這里我們創(chuàng)建一個隨機(jī)的新名字(這在實(shí)踐中可能是一個 UUID)并將新文件名記錄下來。

fileName := randToken(12)
fileEndings, err := mime.ExtensionsByType(fileType)
if err != nil {
renderError(w, "CANT_READ_FILE_TYPE", http.StatusInternalServerError)
return
}
newPath := filepath.Join(uploadPath, fileName+fileEndings[0])
fmt.Printf("FileType: %s, File: %s\n", fileType, newPath)

馬上就大功告成了,只剩下一個關(guān)鍵步驟-寫文件。如上文所提到的,我們只需要復(fù)制讀取的二進(jìn)制文件到一個新創(chuàng)建的名為 newFile 的文件處理程序里。

如果所有部分都沒問題,我們給用戶返回一個 SUCCESS 信息。

newFile, err := os.Create(newPath)
if err != nil {
renderError(w, "CANT_WRITE_FILE", http.StatusInternalServerError)
return
}
defer newFile.Close()
if _, err := newFile.Write(fileBytes); err != nil {
renderError(w, "CANT_WRITE_FILE", http.StatusInternalServerError)
return
}
w.Write([]byte("SUCCESS"))

這樣可以了. 你可以對這個簡單的例子進(jìn)行測試,使用虛擬的文件上傳 HTML 頁面,cURL 或者工具例如 postman [1] 。

這里是完整的代碼示例 這里 [2]

結(jié)論 這是又一個證明了 Go 如何允許用戶為 Web 編寫簡單而強(qiáng)大的軟件,而不必像處理其他語言和生態(tài)系統(tǒng)中固有的無數(shù)抽象層。

在接下來的篇幅中,我將展示一些在我第一次使用 Go 語言編寫正式的 Web 應(yīng)用中其他細(xì)節(jié),敬請期待。;)

// 根據(jù) reddit 用戶 lstokeworth 的反饋對部分代碼進(jìn)行了修改。謝謝:)

到此這篇關(guān)于 Go 語言完成 HTTP 文件上傳和下載的文章就介紹到這了,更多相關(guān) Go HTTP 文件上傳內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go語言計(jì)算指定年月天數(shù)的方法

    Go語言計(jì)算指定年月天數(shù)的方法

    這篇文章主要介紹了Go語言計(jì)算指定年月天數(shù)的方法,實(shí)例分析了Go語言操作時間的技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-02-02
  • go實(shí)現(xiàn)base64編碼的四種方式

    go實(shí)現(xiàn)base64編碼的四種方式

    本文主要介紹了go實(shí)現(xiàn)base64編碼的四種方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • golang中Context的使用場景

    golang中Context的使用場景

    context包提供了一種在goroutine之間傳遞信號的方法,用于管理請求的生命周期和控制并發(fā)操作,本文主要介紹了golang中Context的使用場景,下面就來介紹一下,感興趣的可以了解一下
    2025-05-05
  • Gin與Mysql實(shí)現(xiàn)簡單Restful風(fēng)格API實(shí)戰(zhàn)示例詳解

    Gin與Mysql實(shí)現(xiàn)簡單Restful風(fēng)格API實(shí)戰(zhàn)示例詳解

    這篇文章主要為大家介紹了Gin與Mysql實(shí)現(xiàn)簡單Restful風(fēng)格API示例詳解,有需要的朋友可以借鑒參考下希望能夠有所幫助,祝大家多多進(jìn)步
    2021-11-11
  • Golang語言實(shí)現(xiàn)gRPC的具體使用

    Golang語言實(shí)現(xiàn)gRPC的具體使用

    本文主要介紹了Golang語言實(shí)現(xiàn)gRPC的具體使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • Go語言使用Gob傳輸數(shù)據(jù)

    Go語言使用Gob傳輸數(shù)據(jù)

    本文主要介紹了Go語言使用Gob傳輸數(shù)據(jù),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • Go異步任務(wù)解決方案之Asynq庫詳解

    Go異步任務(wù)解決方案之Asynq庫詳解

    需要在Go應(yīng)用程序中異步處理任務(wù)? Asynq,簡單高效的任務(wù)隊(duì)列實(shí)現(xiàn),下面這篇文章主要給大家介紹了關(guān)于Go異步任務(wù)解決方案之Asynq庫的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • 詳解在Go語言單元測試中如何解決文件依賴問題

    詳解在Go語言單元測試中如何解決文件依賴問題

    現(xiàn)如今的?Web?應(yīng)用程序往往采用?RESTful?API?接口形式對外提供服務(wù),后端接口直接向前端返回?HTML?文件的情況越來越少,所以在程序中操作文件的場景也變少了,在編寫單元測試時,文件就成了被測試代碼的外部依賴,本文就來講解下測試過程中如何解決文件外部依賴問題
    2023-08-08
  • k8s容器互聯(lián)flannel?vxlan通信原理

    k8s容器互聯(lián)flannel?vxlan通信原理

    這篇文章主要為大家介紹了k8s容器互聯(lián)flannel?vxlan通信原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • Goland 2020或2019軟件版本去掉a...或fmt...提示的方法

    Goland 2020或2019軟件版本去掉a...或fmt...提示的方法

    這篇文章主要介紹了Goland 2020或2019軟件版本去掉a...或fmt...提示的方法,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-10-10

最新評論

通州市| 阜宁县| 高碑店市| 桐城市| 阜平县| 华池县| 永新县| 永登县| 安徽省| 金堂县| 德令哈市| 横峰县| 四川省| 雷州市| 理塘县| 安西县| 巨鹿县| 平陆县| 庆安县| 靖江市| 菏泽市| 汉川市| 民县| 遂昌县| 丰原市| 吉木乃县| 阿鲁科尔沁旗| 江西省| 梨树县| 河曲县| 陇西县| 崇义县| 临西县| 永新县| 榕江县| 安阳市| 奉化市| 香港| 萨迦县| 水城县| 新干县|