GoFrame HTTPClient-文件上傳

2022-04-14 11:03 更新

?GoFrame?支持非常方便的表單文件上傳功能,并且?HTTP?客戶端對上傳功能進(jìn)行了必要的封裝并極大簡化了上傳功能調(diào)用。

注意哦:上傳文件大小受到?ghttp.Server?的?ClientMaxBodySize?配置影響:https://pkg.go.dev/github.com/gogf/gf/v2/net/ghttp#ServerConfig 默認(rèn)支持的上傳文件大小為?8MB?。

服務(wù)端

package main

import (
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
)

// Upload uploads files to /tmp .
func Upload(r *ghttp.Request) {
	files := r.GetUploadFiles("upload-file")
    names, err := files.Save("/tmp/")
    if err != nil {
		r.Response.WriteExit(err)
	}
	r.Response.WriteExit("upload successfully: ", names)
}

// UploadShow shows uploading simgle file page.
func UploadShow(r *ghttp.Request) {
	r.Response.Write(`
    <html>
    <head>
        <title>GF Upload File Demo</title>
    </head>
        <body>
            <form enctype="multipart/form-data" action="/upload" method="post">
                <input type="file" name="upload-file" />
                <input type="submit" value="upload" />
            </form>
        </body>
    </html>
    `)
}

// UploadShowBatch shows uploading multiple files page.
func UploadShowBatch(r *ghttp.Request) {
	r.Response.Write(`
    <html>
    <head>
        <title>GF Upload Files Demo</title>
    </head>
        <body>
            <form enctype="multipart/form-data" action="/upload" method="post">
                <input type="file" name="upload-file" />
                <input type="file" name="upload-file" />
                <input type="submit" value="upload" />
            </form>
        </body>
    </html>
    `)
}

func main() {
	s := g.Server()
	s.Group("/upload", func(group *ghttp.RouterGroup) {
		group.POST("/", Upload)
		group.ALL("/show", UploadShow)
		group.ALL("/batch", UploadShowBatch)
	})
	s.SetPort(8199)
	s.Run()
}

該服務(wù)端提供了3個(gè)接口:

我們這里訪問 http://127.0.0.1:8199/upload/show 選擇需要上傳的單個(gè)文件,提交之后可以看到文件上傳成功到服務(wù)器上。

關(guān)鍵代碼說明

  • 我們在服務(wù)端可以通過?r.GetUploadFiles?方法獲得上傳的所有文件對象,也可以通過?r.GetUploadFile?獲取單個(gè)上傳的文件對象。
  • 在?r.GetUploadFiles("upload-file")?中的參數(shù)?"upload-file"?為本示例中客戶端上傳時(shí)的表單文件域名稱,開發(fā)者可以根據(jù)前后端約定在客戶端中定義,以方便服務(wù)端接收表單文件域參數(shù)。
  • 通過?files.Save?可以將上傳的多個(gè)文件方便地保存到指定的目錄下,并返回保存成功的文件名。如果是批量保存,只要任意一個(gè)文件保存失敗,都將會立即返回錯(cuò)誤。此外,?Save?方法的第二個(gè)參數(shù)支持隨機(jī)自動(dòng)命名上傳文件。
  • 通過?group.POST("/", Upload)?注冊的路由僅支持?POST?方式訪問。

客戶端

單文件上傳

package main

import (
    "fmt"

    "github.com/gogf/gf/v2/net/ghttp"
    "github.com/gogf/gf/v2/os/glog"
)

func main() {
    path := "/home/john/Workspace/Go/github.com/gogf/gf/v2/version.go"
    r, e := ghttp.Post("http://127.0.0.1:8199/upload", "upload-file=@file:"+path)
    if e != nil {
        glog.Error(e)
    } else {
        fmt.Println(string(r.ReadAll()))
        r.Close()
    }
}

注意到了嗎?文件上傳參數(shù)格式使用了 ?參數(shù)名=@file:文件路徑? ,?HTTP?客戶端將會自動(dòng)解析文件路徑對應(yīng)的文件內(nèi)容并讀取提交給服務(wù)端。原本復(fù)雜的文件上傳操作被gf進(jìn)行了封裝處理,用戶只需要使用 ?@file:+文件路徑? 來構(gòu)成參數(shù)值即可。其中,文件路徑請使用本地文件絕對路徑。

首先運(yùn)行服務(wù)端程序之后,我們再運(yùn)行這個(gè)上傳客戶端(注意修改上傳的文件路徑為本地真實(shí)文件路徑),執(zhí)行后可以看到文件被成功上傳到服務(wù)器的指定路徑下。

多文件上傳

package main

import (
	"fmt"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/os/glog"
)

func main() {
	path1 := "/Users/john/Pictures/logo1.png"
	path2 := "/Users/john/Pictures/logo2.png"
	r, e := ghttp.Post(
		"http://127.0.0.1:8199/upload",
		fmt.Sprintf(`upload-file=@file:%s&upload-file=@file:%s`, path1, path2),
	)
	if e != nil {
		glog.Error(e)
	} else {
		fmt.Println(string(r.ReadAll()))
		r.Close()
	}
}

可以看到,多個(gè)文件上傳提交參數(shù)格式為?參數(shù)名=@file:xxx&參數(shù)名=@file:xxx...?,也可以使用?參數(shù)名[]=@file:xxx&參數(shù)名[]=@file:xxx...?的形式。

首先運(yùn)行服務(wù)端程序之后,我們再運(yùn)行這個(gè)上傳客戶端(注意修改上傳的文件路徑為本地真實(shí)文件路徑),執(zhí)行后可以看到文件被成功上傳到服務(wù)器的指定路徑下。

自定義文件名稱

很簡單,修改?FileName?屬性即可。

s := g.Server()
s.BindHandler("/upload", func(r *ghttp.Request) {
    file := r.GetUploadFile("TestFile")
    if file == nil {
        r.Response.Write("empty file")
        return
    }
    file.Filename = "MyCustomFileName.txt"
    fileName, err := file.Save(gfile.TempDir())
    if err != nil {
        r.Response.Write(err)
        return
    }
    r.Response.Write(fileName)
})
s.SetPort(8999)
s.Run()


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號