本文主要是介绍拖拽传图 Iris + DropzoneJS,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Iris官方其实很厚道,有很多有用的例子,而社区则是文档多于实战。源于官方示例库([英文源文])(https://github.com/kataras/iris/tree/master/_examples/tutorial/dropzonejs),本文采用 DropzoneJS and Go实现图片上传,后端裁剪,前端呈现,代码量少但胜在实用,适合新同学实战。
涉及的点
- DropzoneJS 拖拽上传图片前端库,可显示进度
- Iris 类(理念相近)PHP 中的 Laravel 框架,但比之轻
- 相关同步,图片,文件,路径等标准库
- 第三方库
nfnt/resize
,用于缩略图等比例裁剪
效果图
前端
引入的DropzoneJS库本身不依赖于jQeury,表单亦无需 enctype
,本文只是用jquery向后端发数据
DOM布局
表单 file
类型节点, 要携带 multiple
属性,以示多文件上传
<form action="/upload" method="post" class="dropzone" id="my-dropzone"><div class="fallback"><input type="file" name="file" multiple/><input type="submit" value="Upload"></div></form>
DropzoneJS
addedfile
事件,使用回调数据,其添加到对应的文件对象上去; complete
事件,显示进度条
Dropzone.options.myDropzone ={paramName:"file",init:function(){thisDropzone = this;$.get('/uploads',function(data){if(data==null){return}$.each(data,function(key,value){var mockFile = {name:value.name,size:value.size}thisDropzone.emit("addedfile", mockFile)thisDropzone.options.thumbnail.call(thisDropzone, mockFile, '/public/uploads/thumbnail_'+value.name)// 进度条thisDropzone.emit("complete", mockFile)})})}}
后端
项目目录结构如下
│ main.go
├─public
│ ├─css
│ │ dropzone.css
│ ├─js
│ │ dropzone.js
│ └─uploads
│ kk048.jpg
│ ll031.jpg
│ thumbnail_kk048.jpg
│ thumbnail_ll031.jpg
│ thumbnail_web_spring.png
│ web_spring.png
└─viewsupload.html
数据
文件标签结构体方便前端接收json格式的文件名及大小的信息
const uploadsDir = "./public/uploads/"
type uploadedFile struct {// {name: "", size: } 适应dropzone所需Name string `json:"name"`Size int64 `json:"size"`
}
type uploadedFiles struct {dir string // 文件存储目录items []uploadedFile // 多文件数据记录进切片mu sync.RWMutex // 安全类型的切片锁
}
操作集
对 *uploadedFiles
类型的创建及其方法
// 获取多文件实例
func scanUploads(dir string) *uploadedFiles {f := new(uploadedFiles)index := dir[len(dir)-1]if index != os.PathSeparator && index != '/' {dir += string(os.PathSeparator)}// 递归创建文件夹if err := os.MkdirAll(dir, os.FileMode(0666)); err != nil {return f}f.scan(dir)return f
}func (f *uploadedFiles) scan(dir string) {f.dir = dir// 根目录递归分析,得到图片文件信息filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {// 排除目录及缩略图if info.IsDir() || strings.HasPrefix(info.Name(), "thumbnail_") {return nil}// 添加非缩略图文件f.add(info.Name(), info.Size())return nil})
}
// 添加文件信息
func (f *uploadedFiles) add(name string, size int64) uploadedFile {uf := uploadedFile{Name: name,Size: size,}f.mu.Lock()f.items = append(f.items, uf)f.mu.Unlock()return uf
}
// 创建缩略图
func (f *uploadedFiles) createThumbnail(uf uploadedFile) {file, err := os.Open(path.Join(f.dir, uf.Name))if err != nil {return}defer file.Close()name := strings.ToLower(uf.Name)out, err := os.OpenFile(f.dir+"thumbnail_"+uf.Name, os.O_WRONLY|os.O_CREATE, 0666)if err != nil {return}defer out.Close()// 裁剪缩略图if strings.HasSuffix(name, "jpg") {img, err := jpeg.Decode(file)if err != nil {return}resized := resize.Thumbnail(180, 180, img, resize.Lanczos3)// 将图像写入输出流jpeg.Encode(out, resized, &jpeg.Options{Quality: jpeg.DefaultQuality})} else if strings.HasSuffix(name, "png") {img, err := png.Decode(file)if err != nil {return}// 等比例缩放resized := resize.Thumbnail(180, 180, img, resize.Lanczos3)png.Encode(out, resized)}
}
Iris应用
好的代码会说话,上码
func main() {app := iris.New()// 注册视图引擎app.RegisterView(iris.HTML("./views", ".html"))// 发布静态资源服务app.HandleDir("/public", "./public")// 注册首页路由app.Get("/", func(ctx iris.Context) {ctx.View("upload.html")})// 扫描上传后文件信息(缩略图信息)files := scanUploads(uploadsDir)// 多图片信息api查询接口,返回jsonapp.Get("/uploads", func(ctx iris.Context) {ctx.JSON(files.items)})// 注册Post上传app.Post("/upload", iris.LimitRequestBodySize(10<<20), func(ctx iris.Context) {// 多文件上传 ctx是一个集请求与响应的组合体file, info, err := ctx.FormFile("file")if err != nil {ctx.StatusCode(iris.StatusInternalServerError)ctx.Application().Logger().Warnf("Error while uploading: %v", err.Error())return}defer file.Close()fname := info.Filenameout, err := os.OpenFile(uploadsDir+fname, os.O_WRONLY|os.O_CREATE, 0666)if err != nil {ctx.StatusCode(iris.StatusInternalServerError)ctx.Application().Logger().Warnf("Error while preparing the new file: %v", err.Error())return}defer out.Close()// 将文件上传流复制到服务器本地io.Copy(out, file)// 可选 顺序添加文件列表uploadedFile := files.add(fname, info.Size)// goroutine创建缩略图go files.createThumbnail(uploadedFile)})app.Run(iris.Addr("localhost:8080"))
}
参考
源代码
Iris新手指北
这篇关于拖拽传图 Iris + DropzoneJS的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!