Skip to main content

上传与下载

文件上传

文件上传可以通过表单上传,也可以通过Ajax上传,GoFrame框架后端处理都是一样的,所以只演示一下表单上传。

单文件上传

html/upload.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>上传文件</title>
</head>
<body>

<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="ufile"> <br>
<input type="file" name="ufiles" multiple> <br>
<input type="submit" value="上传">
</form>

</body>
</html>

controller/hello.go

func (c *Controller) Upload(req *ghttp.Request) {
file := req.GetUploadFile("ufile")
if file != nil {
file.Filename = "20231001.png" // 可以根据需要给文件重命名
name, err := file.Save("./upload")
if err == nil {
req.Response.Writeln(name)
}
}
}

多文件上传

func (c *Controller) Upload(req *ghttp.Request) {
files := req.GetUploadFiles("ufiles")
if files != nil {
names, err := files.Save("./upload")
if err == nil {
req.Response.Writeln(names)
}
}
}

除了从请求中获取上传文件以外,如果用api规范路由,还可以用如下方式获取上传文件

type UploadReq struct {
g.Meta `path:"/upload" method:"post"`

Ufile ghttp.UploadFile `json:"ufile"`

UFiles ghttp.UploadFiles `json:"ufiles"`
}

使用这种方式,如果文件允许为空, 则可能会发生转换错误。

文件上传应用实例

  • 在静态资源目录新建upload文件夹用于存放上传文件,示例中为resource/public/upload,绑定的静态目录为resource/public,因此可以用/upload/<filename>的形式访问指定文件
  • 将上传文件名称修改为对应文件的哈希值,以防上传同名文件覆盖
  • 返回文件的URL
func (c *Controller) Upload(ctx context.Context, r *api.UploadReq) (res *api.UploadRes, err error) {
req := g.RequestFromCtx(ctx)
file := req.GetUploadFile("ufile")
if file != nil {
var md5str string
md5str, err = gmd5.Encrypt(file)
if err != nil {
return
}
file.Filename = md5str + path.Ext(file.Filename)
name, err := file.Save("resource/public/upload")
if err == nil {
res = &api.UploadRes{
Data: "/upload/" + name,
}
}
}
return
}

文件下载

ServeFile

ServeFile向客户端返回一个文件内容,如果是文本或者图片,将会直接展示,不能直接在浏览器中展示的将进行下载

func (c *Controller) Download(req *ghttp.Request) {
req.Response.ServeFile("upload/1.png")
}

ServeFileDownload

该方法直接引导客户端进行下载,并且可以给下载文件重命名

func (c *Controller) Download(req *ghttp.Request) {
req.Response.ServeFileDownload("upload/1.png", "download.png")
}

上传限制

如果需要限制单次上传文件大小,可以用clientMaxBodySize配置。如果完全不需要限制,直接设为0即可

config.yaml

server:
clientMaxBodySize: "0"