用go iris 写的一个网页版文件共享应用(webapp)
主要演示文件拖拽上传或点击上传到不同的目录中,提供下载和删除功能。
目录结构:
-main.go
--share(用于分类存放上传文件的目录)
--v(视图目录)
---share.html
main.go
//自编了一个文件共享系统,everyone可上传下载,无权限控制,公网使用风险大,需完善 //所有文件将上传到./share/XXX目录下,可通过http://localhost:8080/share/XXX 访问并下载 // package main import ( "fmt" "io" "io/ioutil" "os" "path/filepath" "sort" "github.com/kataras/iris" ) const ( upload_path string = "./share/" ) //表示一个上传的文件 type Upfile struct { Url string //位置,如share/XXX/ Name string //文件名,如abc.doc Date string //文件时间,ModTime转string } //表示权限 type Allow struct { UP bool //可上传 Down bool //可下载 Del bool //可删除 } type Updir []Upfile //表示一个目录当中,所有上传的文件 // 用Len Less Swap使Updir可排序,可用sort.Sort排序 func (d Updir) Len() int { return len(d) } // Date降序 func (d Updir) Less(i, j int) bool { return d[i].Date > d[j].Date } // 交换 func (d Updir) Swap(i, j int) { d[i], d[j] = d[j], d[i] } func main() { fmt.Println("OK!请访问 :8080/share") //启动一个http 服务器 app := iris.New() //静态文件服务 app.StaticWeb("/share", "./share") //注册视图目录 tmpl := iris.HTML("./v", ".html") app.RegisterView(tmpl) //主页 app.Get("/share", func(ctx iris.Context) { ctx.View("main.html") }) //下载 app.Get("/share/{path:alphabetical}", func(ctx iris.Context) { FlagAllowDel := false //允许删除文件标志 //URL中的路径 reqPath := ctx.Path() //如:/share/aaa myfolder := "." + reqPath + "/" //如:./share/aaa/ //获取执行文件路径: rootdir, err := filepath.Abs(filepath.Dir(os.Args[0])) //如:e:\goapp\myapp createf := rootdir + reqPath + "/" //如:e:\goapp\myapp/share/aaa/ _, err = os.Stat(createf) //os.Stat获取文件信息 //判断文件夹path存在,否则创建之 ,绝对路径 if os.IsNotExist(err) { os.MkdirAll(createf, os.ModePerm) } //列出目录下的文件 var upfile Upfile fileins := make(Updir, 0) files, _ := ioutil.ReadDir(myfolder) for _, file := range files { if file.IsDir() { continue } else { upfile.Name = file.Name() upfile.Url = ctx.Path() + "/" + file.Name() upfile.Date = file.ModTime().Format("2006-01-02 15:04:05") fileins = append(fileins, upfile) } } //fmt.Println(fileins[0].Name) //倒序排序 sort.Sort(fileins) ctx.ViewData("FlagAllowDel", FlagAllowDel) ctx.ViewData("Files", fileins) // 渲染视图文件: ./v/index.html ctx.View("share.html") }) //主页管理,与主页共用模板 .v/share.html app.Get("/admin/{path:alphabetical}", func(ctx iris.Context) { FlagAllowDel := true //允许删除文件标志 //列出目录下的文件 var upfile Upfile fileins := make(Updir, 0) myfolder := "./share" + ctx.Path()[6:] + "/" files, _ := ioutil.ReadDir(myfolder) for _, file := range files { if file.IsDir() { continue } else { upfile.Name = file.Name() upfile.Url = ctx.Path() + "/" + file.Name() upfile.Date = file.ModTime().Format("2006-01-02 15:04:05") fileins = append(fileins, upfile) } } //fmt.Println(fileins[0].Name) //倒序排序 sort.Sort(fileins) ctx.ViewData("FlagAllowDel", FlagAllowDel) ctx.ViewData("Files", fileins) // 渲染视图文件: ./v/index.html ctx.View("share.html") }) //上传, 接收用XMLHttpRequest上传的文件 app.Post("/share/{path:alphabetical}", func(ctx iris.Context) { //获取文件内容 file, head, err := ctx.FormFile("upfile") //可参考Get时的路径判断pathwww是否存在,这里省略了... myfolder := "." + ctx.Path() + "/" defer file.Close() //创建文件 fW, err := os.Create(myfolder + head.Filename) if err != nil { fmt.Println("文件创建失败") return } defer fW.Close() _, err = io.Copy(fW, file) if err != nil { fmt.Println("文件保存失败") return } ctx.JSON(iris.Map{"success": true, "res": head.Filename}) }) //下载,未使用 app.Get("/share/down", func(ctx iris.Context) { //无效ctx.Header("Content-Disposition", "attachment;filename=FileName.txt") ctx.ServeFile("./share/1.txt", false) }) //删除 app.Post("/admin/{dir}", func(ctx iris.Context) { path := ctx.PostValue("path") //如 /admin/aaa/111.txt myfolder := "./share" + path[6:] fmt.Println(myfolder) os.Remove(myfolder) ctx.JSON(iris.Map{"success": true, "res": "aaaaaaaaaaaa"}) }) app.Run(iris.Addr(":8080")) }
share.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>{{.Title}}</title> <style> .file_upload_box { display: inline-block; width: 200px; height: 50px; position: relative; overflow: hidden; } .file_upload_box input[type=file] { position: absolute; left: 0; top: 0; width: 100%; line-height: 50px; opacity: 0; cursor: pointer; } .file_upload_box a { display: inline-block; width: 100%; line-height: 50px; text-align: center; font-family: "Microsoft yahei"; background-color: #f60; color: #FFF; font-weight: 700; text-decoration: none; } .flexcontainer{ display:flex; } </style> </head> <body> <div class="flexcontainer"> {{if $.FlagAllowDel}} <span>管理面板</span> {{else}} <div id="fileSpan" style="background-color:#FFE;width:100%;height:50px">请将文件拖到这里上传(覆盖同名文件)</div> <div class="file_upload_box"> <input type="file" name="file" onchange="upload(this)"/> <a href="#none">上传文件</a> </div> {{end}} </div> <script type="text/javascript"> window.onload = function(){ var uuz = document.getElementById(\'fileSpan\'); uuz.ondragenter = function(e){ e.preventDefault(); } uuz.ondragover = function(e){ e.preventDefault(); this.innerHTML = \'请松开鼠标\'; this.style.cssText="background-color:#EFF;width:100%;height:50px;" } uuz.ondragleave = function(e){ e.preventDefault(); this.innerHTML = \'请将文件拖到这里上传\'; this.style.cssText="background-color:#FFE;width:100%;height:50px;" } uuz.ondrop = function(e){ e.preventDefault(); this.innerHTML = \'请将文件拖到这里上传\'; var upfile = e.dataTransfer.files[0]; //获取要上传的文件对象(可以上传多个) // alert(upfile.name) //alert(upfile.type) var formdata = new FormData(); var xhr = new XMLHttpRequest(); formdata.append(\'upfile\', upfile); //设置服务器端接收的name为upfile xhr.open("post",""); xhr.onreadystatechange = function(){ if(this.readyState==4){ if(this.status==200){ //上传成功 var resultText = this.responseText; console.info(resultText); //转json var jsonObj = JSON.parse(resultText); console.info(jsonObj); if(jsonObj.success){ //var oUl = document.getElementById(\'ul1\'); //var oLi = document.createElement(\'li\'); //var oSpan = document.createElement(\'span\'); //oSpan.innerHTML = jsonObj.res +" 刚才上传"; //oLi.appendChild(oSpan); //oUl.insertBefore(oLi, oUl.children[0]); //刷新 window.location.reload(); } }else{ alert(\'上传失败,请使用另一种方式上传\'); } } } xhr.send(formdata); } } function upload(e){ var upfile = e.files[0]; var formdata = new FormData(); var xhr = new XMLHttpRequest(); formdata.append(\'upfile\', upfile); //设置服务器端接收的name为upfile xhr.open("post",""); xhr.onreadystatechange = function(){ if(this.readyState==4){ if(this.status==200){ //上传成功 var resultText = this.responseText; //转json var jsonObj = JSON.parse(resultText); console.info(jsonObj); if(jsonObj.success){ //刷新 window.location.reload(); } } } } xhr.send(formdata); } </script> <div><a href="/share">返回总目录</a> - 本目录文件</div> <ul id="ul1" > {{range $i, $v := .Files}} <li style="line-height:200%"> <span> {{$v.Name}} </span> <span> {{$v.Date}} </span> {{if $.FlagAllowDel}} <span> <a href=\'#\' onclick="del({{$v.Url}})" >删除</a> </span> {{else}} <span> <a href={{$v.Url}} download={{$v.Name}}>下载</a> </span> {{end}} </li> {{end}} </ul> <script type="text/javascript"> function del(path){ //alert(path); var formdata = new FormData(); var xhr = new XMLHttpRequest(); formdata.append(\'path\', path); //设置服务器端接收 xhr.open("post",""); xhr.onreadystatechange = function(){ if(this.readyState==4){ if(this.status==200){ //成功 window.location.reload(); } }else{ //alert(\'删除失败\'); } } xhr.send(formdata); } </script> </body> </html>