ZBLOG

golang web文件上传

Golang Web 文件上传实现

在 Go 语言中实现 Web 文件上传功能有多种方式,下面我将介绍几种常见的实现方法。

1. 基本文件上传

package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func uploadHandler(w http.ResponseWriter, r *http.Request) {
	// 限制上传文件大小 (例如10MB)
	r.ParseMultipartForm(10 << 20)
	
	// 获取上传的文件
	file, handler, err := r.FormFile("myFile")
	if err != nil {
		fmt.Println("Error Retrieving the File")
		fmt.Println(err)
		return
	}
	defer file.Close()
	
	fmt.Printf("Uploaded File: %+v\n", handler.Filename)
	fmt.Printf("File Size: %+v\n", handler.Size)
	fmt.Printf("MIME Header: %+v\n", handler.Header)

	// 创建目标文件
	dst, err := os.Create(handler.Filename)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	defer dst.Close()
	
	// 复制文件内容到目标文件
	if _, err := io.Copy(dst, file); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	
	fmt.Fprintf(w, "Successfully Uploaded File\n")
}

func main() {
    http.HandleFunc("/upload", uploadHandler)
    http.ListenAndServe(":8080", nil)
}

2. Gin框架实现文件上传

如果你使用Gin框架,可以这样实现:

package main

import (
    "github.com/gin-gonic/gin"
    "net/http"
)

func main() {
    router := gin.Default()
    
    // Set a lower memory limit for multipart forms (default is 32 MiB)
    router.MaxMultipartMemory = 8 << 20 // 8 MiB
    
    router.POST("/upload", func(c *gin.Context) {
        // Single file
        file, _ := c.FormFile("file")
        
        // Upload the file to specific dst.
        dst := "./uploads/" + file.Filename
        c.SaveUploadedFile(file, dst)
        
        c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
    })
    
    router.Run(":8080")
}

3. 多文件上传

func multipleUploadHandler(c *gin.Context) {
    form, _ := c.MultipartForm()
    files := form.File["files"]

    for _, file := range files {
        dst := "./uploads/" + file.Filename
        if err := c.SaveUploadedFile(file, dst); err != nil {
            c.String(http.StatusInternalServerError, fmt.Sprintf("upload file error: %s", err.Error()))
            return
        }
    }
    
    c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
}

4. 安全注意事项

  1. 验证文件类型:不要仅依赖Content-Type,检查文件的魔数(magic number)
func isImage(fileHeader *multipart.FileHeader) bool {
    src, err := fileHeader.Open()
    if err != nil {
        return false
    }
    defer src.Close()

	buff := make([]byte, 512) // why read only first bytes? - see https://golang.org/pkg/net/http/#DetectContentType 
	if _, err = src.Read(buff); err != nil { 
	    return false 
   } 

   switch http.DetectContentType(buff) { 
       case "image/jpeg", "image/png": 
           return true 
       default: 
           return false 
   }
}
  1. 重命名上传的文件:避免文件名冲突和安全问题

  2. 设置大小限制:防止DoS攻击

  3. 存储路径安全:确保不能通过URL访问到敏感目录

  4. 病毒扫描:对上传的文件进行病毒扫描(可集成clamav等)

希望这些信息对你有所帮助!如果需要更详细的某个部分或有其他问题,请告诉我。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=23774

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?