使用Golang构建轻量级图床的核心是实现文件上传接收、文件存储以及可访问URL生成三个核心环节,整个流程不需要引入重型框架,仅用标准库就能完成基础功能的搭建,同时可以根据自身需求扩展更多特性。

核心功能模块设计
轻量级图床的核心功能可以分为三个部分,每个部分职责清晰,方便后续维护扩展:
- 文件上传模块:负责接收前端传递的图片文件,完成文件类型、大小等合法性校验,避免非法文件上传。
- 文件存储模块:将校验通过的图片保存到服务器指定目录,同时生成唯一的文件名称,避免文件名冲突。
- URL生成模块:根据存储的文件路径,生成对外可访问的HTTP URL,用户可以通过该URL访问到上传的图片。
文件上传与校验实现
首先实现文件上传的接口,使用Golang标准库的net/http包处理请求,同时需要限制上传的文件类型和大小,避免存储无用文件或者占用过多服务器空间。
package main
import (
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"time"
)
// 允许上传的图片类型
var allowedTypes = map[string]bool{
"image/jpeg": true,
"image/png": true,
"image/gif": true,
}
// 最大上传文件大小 10MB
const maxUploadSize = 10 << 20
// 上传文件处理函数
func uploadHandler(w http.ResponseWriter, r *http.Request) {
// 限制请求体大小
r.Body = http.MaxBytesReader(w, r.Body, maxUploadSize)
if err := r.ParseMultipartForm(maxUploadSize); err != nil {
http.Error(w, "上传文件过大", http.StatusBadRequest)
return
}
// 获取上传的文件
file, header, err := r.FormFile("image")
if err != nil {
http.Error(w, "获取上传文件失败", http.StatusBadRequest)
return
}
defer file.Close()
// 校验文件类型
contentType := header.Header.Get("Content-Type")
if !allowedTypes[contentType] {
http.Error(w, "不支持的文件类型,仅支持jpeg、png、gif", http.StatusBadRequest)
return
}
// 生成唯一文件名,避免冲突
fileExt := filepath.Ext(header.Filename)
newFileName := fmt.Sprintf("%d%s", time.Now().UnixNano(), fileExt)
// 存储目录,不存在则创建
saveDir := "./uploads"
if err := os.MkdirAll(saveDir, 0755); err != nil {
http.Error(w, "创建存储目录失败", http.StatusInternalServerError)
return
}
savePath := filepath.Join(saveDir, newFileName)
// 创建目标文件
dst, err := os.Create(savePath)
if err != nil {
http.Error(w, "创建文件失败", http.StatusInternalServerError)
return
}
defer dst.Close()
// 复制文件内容
if _, err := io.Copy(dst, file); err != nil {
http.Error(w, "保存文件失败", http.StatusInternalServerError)
return
}
}
URL生成与静态文件服务
文件存储完成后,需要生成可访问的URL,同时需要让服务器能够提供存储目录下的静态文件访问能力,用户才能通过URL访问到图片。
// 生成图片访问URL
func generateImageURL(fileName string, baseURL string) string {
return fmt.Sprintf("%s/uploads/%s", baseURL, fileName)
}
// 添加上传接口和静态文件服务
func main() {
// 处理上传请求
http.HandleFunc("/upload", uploadHandler)
// 提供uploads目录的静态文件访问
http.Handle("/uploads/", http.StripPrefix("/uploads/", http.FileServer(http.Dir("./uploads"))))
// 启动服务,监听8080端口
baseURL := "http://127.0.0.1:8080"
fmt.Printf("图床服务启动,监听端口8080,访问地址:%sn", baseURL)
if err := http.ListenAndServe(":8080", nil); err != nil {
fmt.Printf("服务启动失败:%vn", err)
}
}
接口调用示例
可以使用curl命令测试上传接口,上传完成后会返回对应的图片URL:
# 上传图片
curl -F "image=@./test.jpg" http://127.0.0.1:8080/upload
# 上传成功后会输出类似内容:{"url":"http://127.0.0.1:8080/uploads/1698765432109876547.jpg"}
优化建议
基础的图床功能完成后,可以根据需求做进一步优化:
- 添加身份校验,避免未授权的用户上传文件,防止服务器被滥用。
- 增加图片压缩功能,上传时对大图片进行压缩,减少存储空间占用。
- 替换本地存储为对象存储,比如兼容S3协议的服务,提升文件的可用性和访问速度。
- 添加文件去重逻辑,相同内容的文件只存储一份,节省存储资源。