首页

Go iris框架单文件上传与多文件上传

Go iris框架是一款优秀的web框架,功能强大,可以谓包罗万象,不论你是使用接近原生态的模版创建网站,还是使用mvc都非常得心应手;同时还支持依赖注入,orm映射,websocket,webassembly等。这篇文章介绍文件上传:单一文件上传,多文件上传。下面我将提供全部代码,css文件是个空文件,并无样式,为以后扩充用,jquery文件请自行下载。

单文件上传的模版页面 templates/upload_form.html
<html>

<head>
<title>Upload file</title>
</head>

<body>
<form enctype="multipart/form-data" action="/upload" method="POST">
<input type="file" name="uploadfile" />
<input type="hidden" name="token" value="{{.}}" />
<input type="submit" value="upload" />
</form>
</body>

</html>

多文件上传的模版页面 templates/upload_form2.html
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0" />
<meta name="keywords" content="">
<meta name="description" content="">
<link href="/css/site.css" rel="stylesheet">
<script type="text/javascript" src="/js/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="/js/util.js"></script>
<script type="text/javascript" src="/js/uf.js"></script>
<title>Upload files</title>
</head>

<body>
<form name="tform" id="tform">
<div class="item" style="position: relative;">
<div style="background: transparent;">
<input id="uploadfile" style="position: relative;" type="file" name="uploadfile" multiple="multiple">
</div>
</div>
<div id="picdiv" style="margin-top:10px;"></div>
</form>
</body>

</html>

脚本文件js/util.js,ajax方式上传文件
(function($) {
$.fn.extend({
"upload": function(url, callback) {
var that = this;
if (that.val()) {
var formData = new FormData(that.parents("form")[0]);
$.ajax({
async: true,
cache: false,
contentType: false,
processData: false,
type: "POST",
dataType: "text",
url: url,
data: formData,
error: function(e) {
that.val("");
},
success: function(data) {
that.val("");
if (jQuery.isFunction(callback)) {
callback.call(null, data);
}
}
});
}
}
});
})(window.jQuery);

业务脚本 js/uf.js,将上传的文件并排显示
$(document).ready(function() {
$("#uploadfile").change(function() {
$("#uploadfile").upload('/upload2', function(data) {
var urls = data.split('|');
urls.forEach(element => {
if (!!element)
$("#picdiv").append("<img style='height:60px;margin-left:10px;' src='" + element + "'>");
});
});
});
});

Go语言代码 mian.go
package main

import (
    "crypto/md5"
    "fmt"
    "io"
    "mime/multipart"
    "os"
    "strconv"
    "strings"
    "time"

    "github.com/kataras/iris"
)

// 5MB
const maxSize = 5 << 20

func main() {
    app := iris.New()

    app.RegisterView(iris.HTML("./templates", ".html").Reload(true))

    // 1. 第一种上传方式,token可以用来加密认证,这里并未使用到
    app.Get("/upload", func(ctx iris.Context) {
        now := time.Now().Unix()
        h := md5.New()
        io.WriteString(h, strconv.FormatInt(now, 10))
        token := fmt.Sprintf("%x", h.Sum(nil))

        ctx.View("upload_form.html", token)
    })

    // 处理上传请求,并保存文件到目录
    app.Post("/upload", iris.LimitRequestBodySize(maxSize+1<<20), func(ctx iris.Context) {
        file, info, err := ctx.FormFile("uploadfile")
        if err != nil {
            ctx.StatusCode(iris.StatusInternalServerError)
            ctx.HTML("Error while uploading: <b>" + err.Error() + "</b>")
            return
        }

        defer file.Close()
        fname := info.Filename

        out, err := os.OpenFile("./uploads/"+fname, os.O_WRONLY|os.O_CREATE, 0666)

        if err != nil {
            ctx.StatusCode(iris.StatusInternalServerError)
            ctx.HTML("Error while uploading: <b>" + err.Error() + "</b>")
            return
        }
        defer out.Close()
        io.Copy(out, file)

        ctx.JSON(iris.Map{
            "status": true,
            "message": "ok",
        })
    })

    // 2. 第二种文件上传方式,支持多文件
    app.Get("/upload2", func(ctx iris.Context) {
        ctx.View("upload_form2.html")
    })

    // 接收上传请求,支持多文件
    app.Post("/upload2", iris.LimitRequestBodySize(maxSize), func(ctx iris.Context) {
        ctx.UploadFormFiles("./uploads", beforeSave)
    })

    app.StaticWeb("/css", "./assets/css")
    app.StaticWeb("/js", "./assets/js")
    app.StaticWeb("/uploads", "./uploads")

    app.Run(iris.Addr(":8080"), iris.WithPostMaxMemory(maxSize))
}

func beforeSave(ctx iris.Context, file *multipart.FileHeader) {
    ip := ctx.RemoteAddr()
    ip = strings.Replace(ip, ".", "_", -1)
    ip = strings.Replace(ip, ":", "_", -1)
    file.Filename = ip + "-" + file.Filename

    ctx.Writef("|%s", "/uploads/"+file.Filename)
}


Go文件重要地方都加上了注释,这里还限制了上传文件的大小,以及用户可以扩充token的使用,增加安全性。展示页面的效果图(上面是单文件上传,下面是多文件上传):

from 爱施园
Posted by 森林 on 2019/02/04
Copyright ©2018 爱施园 粤ICP备14091834号