golang的一个文件服务器

[复制链接]
3290|18
 楼主 | 2019-9-19 15:04 | 显示全部楼层 |阅读模式
可以显示指定目录,进入子目录,下载文件,上传文件等等

@sherwin @海中水 @gaoyang9992006

  1. go run fileserver.go -p=1234
复制代码



显示指定目录:

50095d832723bc965.png



进入子目录:
986215d8327b818bf4.png


上传文件:

428465d832866d82fd.png



fileserver.go
代码如下:


  1. package main

  2. import (
  3.         "flag"
  4.         "fmt"
  5.         "io"
  6.         "io/ioutil"
  7.         "log"
  8.         "net/http"
  9.         "os"
  10.         "path"
  11.         "strconv"
  12.         "strings"
  13.         "time"
  14. )

  15. var defaultPath string

  16. var baseURL string
  17. var upload_path string

  18. func Logger(req *http.Request, statusCode int) {
  19.         const layout = "[ 2/Jan/2006 15:04:05 ]"
  20.         fmt.Println(baseURL + " --- " + time.Now().Format(layout) + " " + req.Method + "  " + strconv.Itoa(statusCode) + "  " + req.URL.Path)
  21. }

  22. func Handler(w http.ResponseWriter, req *http.Request) {


  23.         filename := defaultPath + req.URL.Path[1:]
  24.         fmt.Println("=+=== file name: ",filename)
  25.         if last := len(filename) - 1; last >= 0 && filename[last] == '/' && len(filename) != 1 {
  26.                 filename = filename[:last]
  27.         }

  28.         if req.Method == "POST" {
  29.                 file, head, err := req.FormFile("file")
  30.                 if err != nil {
  31.                         fmt.Println(err)
  32.                         return
  33.                 }

  34.                 defer file.Close()


  35.                 //创建文件
  36.                 fW, err := os.Create(upload_path + head.Filename)
  37.                 if err != nil {
  38.                         fmt.Println("文件创建失败")
  39.                         return
  40.                 }
  41.                 defer fW.Close()

  42.                 _, err = io.Copy(fW, file)
  43.                 if err != nil {
  44.                         fmt.Println("文件保存失败")
  45.                         return
  46.                 }
  47.         }

  48.         // Empty request (Root)
  49.         if filename == "" {
  50.                 filename = "./"
  51.         }

  52.         file, err := os.Stat(filename)

  53.         // 404 if file doesn't exist
  54.         if os.IsNotExist(err) {
  55.                 _, err = io.WriteString(w, "404 Not Found")
  56.                 Logger(req, http.StatusNotFound)
  57.                 return
  58.         }

  59.         // Serve directory
  60.         if file.IsDir() {

  61.                 slashCheck := ""

  62.                 files, err := ioutil.ReadDir(filename)
  63.                 // Catch the Error in reading from directory
  64.                 if err != nil {
  65.                         http.Redirect(w, req, "", http.StatusInternalServerError)
  66.                         Logger(req, http.StatusInternalServerError)
  67.                 }
  68.                 // Checking for Root Directory
  69.                 if filename != "./" {
  70.                         if filename[len(filename)-1] != '/' {
  71.                                 slashCheck = "/"
  72.                         }
  73.                 }

  74.                 fmt.Println("=+=== slashCheck: ",slashCheck)
  75.                 fmt.Println("=+=== req.URL.Path[0:]: ",req.URL.Path[0:])

  76.                 responseString := "<html><body> <h3> Directory Listing for " + req.URL.Path[1:] + "/ </h3> <br/> <hr> <ul>"
  77.                 for _, f := range files {
  78.                         if f.Name()[0] != '.' {
  79.                                 if f.IsDir() {
  80.                                         responseString += "<li><a href=\"" + req.URL.Path[0:] + slashCheck + f.Name() + "\">" + f.Name() + "/" + "</a></li>"
  81.                                 } else {
  82.                                         responseString += "<li><a href=\"" + req.URL.Path[0:] + slashCheck + f.Name() + "\">" + f.Name() + "</a></li>"
  83.                                 }
  84.                         }
  85.                 }

  86.                 //Ending the list
  87.                 responseString += "</ul><br/><hr/>"

  88.                 p := req.URL.Path

  89.                 // Display link to parent directory
  90.                 if len(p) > 1 {
  91.                         base := path.Base(p)

  92.                         slice := len(p) - len(base) - 1

  93.                         url := "/"

  94.                         if slice > 1 {
  95.                                 url = req.URL.Path[:slice]
  96.                                 url = strings.TrimRight(url, "/") // Remove extra / at the end
  97.                         }

  98.                         responseString += "<br/><a href=\"" + url + "\">Parent directory</a>"
  99.                 }

  100.                 uploadStr := "<form action='#' method=\"post\" enctype=\"multipart/form-data\"> <label> </label><input type=\"file\" name='file'  /><br/><br/> <label><input type=\"submit\" value=\"上传文件\"/></label> </form>"

  101.                 responseString = responseString + uploadStr + "</body></html>"
  102.                 //fmt.Println("      =+=== responseString: ",responseString)
  103.                 _, err = io.WriteString(w, responseString)
  104.                 if err != nil {
  105.                         // panic(err)
  106.                         http.Redirect(w, req, "", http.StatusInternalServerError)
  107.                         Logger(req, http.StatusInternalServerError)
  108.                 } else {
  109.                         Logger(req, http.StatusOK)
  110.                 }

  111.                 upload_path = "./" + req.URL.Path[0:] + "/"

  112.                 return
  113.         }

  114.         // File exists and is no directory; Serve the file

  115.         b, err := ioutil.ReadFile(filename)
  116.         if err != nil {
  117.                 http.Redirect(w, req, "", http.StatusInternalServerError)
  118.                 Logger(req, http.StatusInternalServerError)
  119.                 return
  120.         }

  121.         str := string(b)
  122.         extension := path.Ext(filename)

  123.         if extension == ".css" {
  124.                 w.Header().Set("Content-Type", "text/css; charset=utf-8")
  125.         } else if extension == ".js" {
  126.                 w.Header().Set("Content-Type", "application/javascript; charset=utf-8")
  127.         }
  128.         _, err = io.WriteString(w, str)
  129.         if err != nil {
  130.                 // panic(err)
  131.                 http.Redirect(w, req, "", http.StatusInternalServerError)
  132.         } else {
  133.                 Logger(req, http.StatusOK)
  134.         }

  135. }

  136. func main() {

  137.         defaultPortPtr := flag.String("p", "", "Port Number")
  138.         defaultPathPtr := flag.String("d", "", "Root Directory")
  139.         flag.Parse()

  140.         portNum := "8080"

  141.         // Handling the command line flags

  142.         // Directory
  143.         if *defaultPathPtr != "" {
  144.                 defaultPath = "./" + *defaultPathPtr + "/"
  145.         } else {
  146.                 defaultPath = ""
  147.         }
  148.         // Port Number
  149.         if *defaultPortPtr != "" {
  150.                 portNum = *defaultPortPtr
  151.         } else {
  152.                 portNum = "8080"
  153.         }

  154.         baseURL = "http://localhost:" + portNum

  155.         fmt.Println("Serving on ", baseURL, " subdirectory ", defaultPath)

  156.         http.HandleFunc("/", Handler)
  157.         err := http.ListenAndServe(":"+portNum, nil)
  158.         if err != nil {
  159.                 log.Fatal("ListenAndServe: ", err)
  160.         }
  161. }
复制代码


使用特权

评论回复
| 2019-9-20 09:14 | 显示全部楼层
不错的东西。给你点个赞。

使用特权

评论回复
 楼主 | 2019-9-20 09:26 | 显示全部楼层
海中水 发表于 2019-9-20 09:14
不错的东西。给你点个赞。

可以交叉编译到嵌入式linux环境里:
env GOOS=linux GOARCH=arm go build -v fileserver.go

这样可以很方便为嵌入式环境增加远程查看,更新,下载功能

使用特权

评论回复
| 2019-9-20 10:29 | 显示全部楼层
相当于一个NAS么?

使用特权

评论回复
 楼主 | 2019-9-20 13:23 | 显示全部楼层
sherwin 发表于 2019-9-20 10:29
相当于一个NAS么?

可以的

使用特权

评论回复
| 2019-9-23 09:18 | 显示全部楼层
keer_zu 发表于 2019-9-20 09:26
可以交叉编译到嵌入式linux环境里:
env GOOS=linux GOARCH=arm go build -v fileserver.go

ok!有空研究一下。

使用特权

评论回复
| 2019-9-23 16:27 | 显示全部楼层
为啥不用gin....可以少些不少代码...

使用特权

评论回复
 楼主 | 2019-9-24 11:42 | 显示全部楼层
icecut 发表于 2019-9-23 16:27
为啥不用gin....可以少些不少代码...

关键还是文件和路径的问题

使用特权

评论回复
| 2019-9-25 09:45 | 显示全部楼层
keer_zu 发表于 2019-9-24 11:42
关键还是文件和路径的问题

这个可以修改的. 你想啊. 很多网页服务器必须对上传的文件进行改名.否则会出现安全问题...改个路径还不简单...

使用特权

评论回复
 楼主 | 2019-10-4 13:21 | 显示全部楼层
icecut 发表于 2019-9-25 09:45
这个可以修改的. 你想啊. 很多网页服务器必须对上传的文件进行改名.否则会出现安全问题...改个路径还不简 ...

也用过gin做了webserver,但是没有仔细了解过gin额外提供了那些东西,比如安全方面的。

使用特权

评论回复
| 2019-10-5 19:00 | 显示全部楼层
keer_zu 发表于 2019-10-4 13:21
也用过gin做了webserver,但是没有仔细了解过gin额外提供了那些东西,比如安全方面的。 ...

你想的太多了...仅仅是个支持中间件的框架

使用特权

评论回复
 楼主 | 2019-10-8 09:58 | 显示全部楼层
icecut 发表于 2019-10-5 19:00
你想的太多了...仅仅是个支持中间件的框架

小i,这是gin版本:


  1. package main

  2. import (
  3.         "flag"
  4.         "fmt"
  5.         "io"
  6.         "io/ioutil"
  7.         "log"
  8.         "net/http"
  9.         "os"
  10.         "path"
  11.         "strconv"
  12.         "strings"
  13.         "time"
  14.         "github.com/gin-gonic/gin"
  15. )

  16. var defaultPath string

  17. var baseURL string
  18. var upload_path string

  19. func Logger(req *http.Request, statusCode int) {
  20.         const layout = "[ 2/Jan/2006 15:04:05 ]"
  21.         fmt.Println(baseURL + " --- " + time.Now().Format(layout) + " " + req.Method + "  " + strconv.Itoa(statusCode) + "  " + req.URL.Path)
  22. }

  23. func Handler(w http.ResponseWriter, req *http.Request) {


  24.         filename := defaultPath + req.URL.Path[1:]
  25.         fmt.Println("=+=== file name: ",filename)
  26.         if last := len(filename) - 1; last >= 0 && filename[last] == '/' && len(filename) != 1 {
  27.                 filename = filename[:last]
  28.         }

  29.         if req.Method == "POST" {
  30.                 file, head, err := req.FormFile("file")
  31.                 if err != nil {
  32.                         fmt.Println(err)
  33.                         return
  34.                 }

  35.                 defer file.Close()


  36.                 //创建文件
  37.                 fW, err := os.Create(upload_path + head.Filename)
  38.                 if err != nil {
  39.                         fmt.Println("文件创建失败")
  40.                         return
  41.                 }
  42.                 defer fW.Close()

  43.                 _, err = io.Copy(fW, file)
  44.                 if err != nil {
  45.                         fmt.Println("文件保存失败")
  46.                         return
  47.                 }
  48.         }

  49.         // Empty request (Root)
  50.         if filename == "" {
  51.                 filename = "./"
  52.         }

  53.         file, err := os.Stat(filename)

  54.         // 404 if file doesn't exist
  55.         if os.IsNotExist(err) {
  56.                 _, err = io.WriteString(w, "404 Not Found")
  57.                 Logger(req, http.StatusNotFound)
  58.                 return
  59.         }

  60.         // Serve directory
  61.         if file.IsDir() {

  62.                 slashCheck := ""

  63.                 files, err := ioutil.ReadDir(filename)
  64.                 // Catch the Error in reading from directory
  65.                 if err != nil {
  66.                         http.Redirect(w, req, "", http.StatusInternalServerError)
  67.                         Logger(req, http.StatusInternalServerError)
  68.                 }
  69.                 // Checking for Root Directory
  70.                 if filename != "./" {
  71.                         if filename[len(filename)-1] != '/' {
  72.                                 slashCheck = "/"
  73.                         }
  74.                 }

  75.                 fmt.Println("=+=== slashCheck: ",slashCheck)
  76.                 fmt.Println("=+=== req.URL.Path[0:]: ",req.URL.Path[0:])

  77.                 responseString := "<html><body> <h3> Directory Listing for " + req.URL.Path[1:] + "/ </h3> <br/> <hr> <ul>"
  78.                 for _, f := range files {
  79.                         if f.Name()[0] != '.' {
  80.                                 if f.IsDir() {
  81.                                         responseString += "<li><a href=\"" + req.URL.Path[0:] + slashCheck + f.Name() + "\">" + f.Name() + "/" + "</a></li>"
  82.                                 } else {
  83.                                         responseString += "<li><a href=\"" + req.URL.Path[0:] + slashCheck + f.Name() + "\">" + f.Name() + "</a></li>"
  84.                                 }
  85.                         }
  86.                 }

  87.                 //Ending the list
  88.                 responseString += "</ul><br/><hr/>"

  89.                 p := req.URL.Path

  90.                 // Display link to parent directory
  91.                 if len(p) > 1 {
  92.                         base := path.Base(p)

  93.                         slice := len(p) - len(base) - 1

  94.                         url := "/"

  95.                         if slice > 1 {
  96.                                 url = req.URL.Path[:slice]
  97.                                 url = strings.TrimRight(url, "/") // Remove extra / at the end
  98.                         }

  99.                         responseString += "<br/><a href=\"" + url + "\">Parent directory</a>"
  100.                 }

  101.                 uploadStr := "<form action='#' method=\"post\" enctype=\"multipart/form-data\"> <label> </label><input type=\"file\" name='file'  /><br/><br/> <label><input type=\"submit\" value=\"上传文件\"/></label> </form>"

  102.                 responseString = responseString + uploadStr + "</body></html>"
  103.                 //fmt.Println("      =+=== responseString: ",responseString)
  104.                 _, err = io.WriteString(w, responseString)
  105.                 if err != nil {
  106.                         // panic(err)
  107.                         http.Redirect(w, req, "", http.StatusInternalServerError)
  108.                         Logger(req, http.StatusInternalServerError)
  109.                 } else {
  110.                         Logger(req, http.StatusOK)
  111.                 }

  112.                 upload_path = "./" + req.URL.Path[0:] + "/"

  113.                 return
  114.         }

  115.         // File exists and is no directory; Serve the file

  116.         b, err := ioutil.ReadFile(filename)
  117.         if err != nil {
  118.                 http.Redirect(w, req, "", http.StatusInternalServerError)
  119.                 Logger(req, http.StatusInternalServerError)
  120.                 return
  121.         }

  122.         str := string(b)
  123.         extension := path.Ext(filename)

  124.         if extension == ".css" {
  125.                 w.Header().Set("Content-Type", "text/css; charset=utf-8")
  126.         } else if extension == ".js" {
  127.                 w.Header().Set("Content-Type", "application/javascript; charset=utf-8")
  128.         }
  129.         _, err = io.WriteString(w, str)
  130.         if err != nil {
  131.                 // panic(err)
  132.                 http.Redirect(w, req, "", http.StatusInternalServerError)
  133.         } else {
  134.                 Logger(req, http.StatusOK)
  135.         }

  136. }


  137. func FileServerGet(c *gin.Context) {
  138.        
  139.         filename := defaultPath + c.Request.URL.Path[1:]
  140.         fmt.Println("=+=== file name: ",filename)
  141.         if last := len(filename) - 1; last >= 0 && filename[last] == '/' && len(filename) != 1 {
  142.                 filename = filename[:last]
  143.         }

  144.         // Empty request (Root)
  145.         if filename == "" {
  146.                 filename = "./"
  147.         }

  148.         file, err := os.Stat(filename)

  149.         // 404 if file doesn't exist
  150.         if os.IsNotExist(err) {
  151.                 _, err = io.WriteString(c.Writer, "404 Not Found")
  152.                 //Logger(c.Request, http.StatusNotFound)
  153.                 return
  154.         }

  155. // Serve directory
  156.         if file.IsDir() {

  157.                 slashCheck := ""

  158.                 files, err := ioutil.ReadDir(filename)
  159.                 // Catch the Error in reading from directory
  160.                 if err != nil {
  161.                         http.Redirect(c.Writer, c.Request, "", http.StatusInternalServerError)
  162.                         //Logger(c.Request, http.StatusInternalServerError)
  163.                 }
  164.                 // Checking for Root Directory
  165.                 if filename != "./" {
  166.                         if filename[len(filename)-1] != '/' {
  167.                                 slashCheck = "/"
  168.                         }
  169.                 }

  170.                 fmt.Println("=+=== slashCheck: ",slashCheck)
  171.                 fmt.Println("=+=== c.Request.URL.Path[0:]: ",c.Request.URL.Path[0:])

  172.                 responseString := "<html><body> <h3> Directory Listing for " + c.Request.URL.Path[1:] + "/ </h3> <br/> <hr> <ul>"
  173.                 for _, f := range files {
  174.                         if f.Name()[0] != '.' {
  175.                                 if f.IsDir() {
  176.                                         responseString += "<li><a href=\"" + c.Request.URL.Path[0:] + slashCheck + f.Name() + "\">" + f.Name() + "/" + "</a></li>"
  177.                                 } else {
  178.                                         responseString += "<li><a href=\"" + c.Request.URL.Path[0:] + slashCheck + f.Name() + "\">" + f.Name() + "</a></li>"
  179.                                 }
  180.                         }
  181.                 }

  182.                 //Ending the list
  183.                 responseString += "</ul><br/><hr/>"

  184.                 p := c.Request.URL.Path

  185.                 // Display link to parent directory
  186.                 if len(p) > 1 {
  187.                         base := path.Base(p)

  188.                         slice := len(p) - len(base) - 1

  189.                         url := "/"

  190.                         if slice > 1 {
  191.                                 url = c.Request.URL.Path[:slice]
  192.                                 url = strings.TrimRight(url, "/") // Remove extra / at the end
  193.                         }

  194.                         responseString += "<br/><a href=\"" + url + "\">Parent directory</a>"
  195.                 }

  196.                 uploadStr := "<form action='#' method=\"post\" enctype=\"multipart/form-data\"> <label> </label><input type=\"file\" name='file'  /><br/><br/> <label><input type=\"submit\" value=\"上传文件\"/></label> </form>"

  197.                 responseString = responseString + uploadStr + "</body></html>"
  198.                 //fmt.Println("      =+=== responseString: ",responseString)
  199.                 _, err = io.WriteString(c.Writer, responseString)
  200.                 if err != nil {
  201.                         // panic(err)
  202.                         http.Redirect(c.Writer, c.Request, "", http.StatusInternalServerError)
  203.                         //Logger(c.Request, http.StatusInternalServerError)
  204.                 } else {
  205.                         //Logger(c.Request, http.StatusOK)
  206.                 }

  207.                 upload_path = "./" + c.Request.URL.Path[0:] + "/"

  208.                 return
  209.         }

  210.         // File exists and is no directory; Serve the file

  211.         b, err := ioutil.ReadFile(filename)
  212.         if err != nil {
  213.                 http.Redirect(c.Writer, c.Request, "", http.StatusInternalServerError)
  214.                 //Logger(c.Request, http.StatusInternalServerError)
  215.                 return
  216.         }

  217.         str := string(b)
  218.         extension := path.Ext(filename)

  219.         if extension == ".css" {
  220.                 c.Writer.Header().Set("Content-Type", "text/css; charset=utf-8")
  221.         } else if extension == ".js" {
  222.                 c.Writer.Header().Set("Content-Type", "application/javascript; charset=utf-8")
  223.         }
  224.         _, err = io.WriteString(c.Writer, str)
  225.         if err != nil {
  226.                 // panic(err)
  227.                 http.Redirect(c.Writer, c.Request, "", http.StatusInternalServerError)
  228.         } else {
  229.                 //Logger(c.Request, http.StatusOK)
  230.         }
  231. }

  232. func FileServerPost(c *gin.Context) {
  233.         file, head, err := c.Request.FormFile ("file")
  234.         if err != nil {
  235.                 fmt.Println(err)
  236.                 return
  237.         }

  238.         defer file.Close()


  239.         //创建文件
  240.         fW, err := os.Create(upload_path + head.Filename)
  241.         if err != nil {
  242.                 fmt.Println("文件创建失败")
  243.                 return
  244.         }
  245.         defer fW.Close()

  246.         _, err = io.Copy(fW, file)
  247.         if err != nil {
  248.                 fmt.Println("文件保存失败")
  249.                 return
  250.         }
  251. }

  252. func main() {

  253.         router := gin.Default()
  254.         router.GET("/",FileServerGet)
  255.         router.POST("/",FileServerPost)


  256.         defaultPortPtr := flag.String("p", "", "Port Number")
  257.         defaultPathPtr := flag.String("d", "", "Root Directory")
  258.         flag.Parse()

  259.         portNum := "8080"

  260.         // Handling the command line flags

  261.         // Directory
  262.         if *defaultPathPtr != "" {
  263.                 defaultPath = "./" + *defaultPathPtr + "/"
  264.         } else {
  265.                 defaultPath = ""
  266.         }
  267.         // Port Number
  268.         if *defaultPortPtr != "" {
  269.                 portNum = *defaultPortPtr
  270.         } else {
  271.                 portNum = "8080"
  272.         }

  273.         baseURL = "http://localhost:" + portNum

  274.         fmt.Println("Serving on ", baseURL, " subdirectory ", defaultPath)
  275. /*
  276.         http.HandleFunc("/", Handler)
  277.         err := http.ListenAndServe(":"+portNum, nil)
  278.         if err != nil {
  279.                 log.Fatal("ListenAndServe: ", err)
  280.         }
  281.         */
  282.         err := http.ListenAndServe(":" + portNum, router)
  283.         if err != nil {
  284.                 log.Fatal("ListenAndServe: ", err)
  285.         }
  286. }
复制代码
@海中水 @gaoyang9992006 @sherwin

使用特权

评论回复
| 2019-10-8 17:40 | 显示全部楼层
// Static serves files from the given file system root.
// Internally a http.FileServer is used, therefore http.NotFound is used instead
// of the Router's NotFound handler.
// To use the operating system's file system implementation,
// use :
//     router.Static("/static", "/var/www")
func (group *RouterGroup) Static(relativePath, root string) IRoutes {
        return group.StaticFS(relativePath, Dir(root, false))
}
看上面的函数注释.

使用特权

评论回复
| 2019-10-8 17:40 | 显示全部楼层
func main() {
        router := gin.Default()
        // 为 multipart forms 设置较低的内存限制 (默认是 32 MiB)
        // router.MaxMultipartMemory = 8 << 20  // 8 MiB
        router.POST("/upload", func(c *gin.Context) {
                // 单文件
                file, _ := c.FormFile("file")
                log.Println(file.Filename)

                // 上传文件至指定目录
                // c.SaveUploadedFile(file, dst)

                c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
        })
        router.Run(":8080")
}

使用特权

评论回复
| 2019-10-8 17:42 | 显示全部楼层
func main() {
        router := gin.Default()
        router.Static("/assets", "./assets")
        router.StaticFS("/more_static", http.Dir("my_file_system"))
        router.StaticFile("/favicon.ico", "./resources/favicon.ico")

        // 监听并在 0.0.0.0:8080 上启动服务
        router.Run(":8080")
}
下载.

文件浏览需要自己写.官方没有

使用特权

评论回复
 楼主 | 2019-10-9 13:42 | 显示全部楼层
icecut 发表于 2019-10-8 17:42
func main() {
        router := gin.Default()
        router.Static("/assets", "./assets")

这个可以实现文件浏览,但是无法扩展文件上传

使用特权

评论回复
| 2019-10-9 14:13 | 显示全部楼层
keer_zu 发表于 2019-10-9 13:42
这个可以实现文件浏览,但是无法扩展文件上传

上一个代码整合进来不就能上传了. 我只是把官方代码贴给你看看. 没用那么大代码量就能完成

使用特权

评论回复
 楼主 | 2019-10-9 14:29 | 显示全部楼层
icecut 发表于 2019-10-9 14:13
上一个代码整合进来不就能上传了. 我只是把官方代码贴给你看看. 没用那么大代码量就能完成 ...

是的,我整合过后不能上传,gin代码实现单纯的文件浏览功能是很简单,但是通过net/http实现的那个,主要功能都是在代码中的html中实现的。gin却很不方便让自己的文件浏览功能(StaticFS)扩展上传或者其他等等。

使用特权

评论回复
| 2019-10-9 17:34 | 显示全部楼层
keer_zu 发表于 2019-10-9 14:29
是的,我整合过后不能上传,gin代码实现单纯的文件浏览功能是很简单,但是通过net/http实现的那个,主要 ...

还是尽量用gin, 原生http真的没人用. 前端的代码尽量js独立完成.

正规办法是用阿里oss等云平台来搞这种上传.太浪费流量

使用特权

评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 投诉建议 创建版块 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

关闭

热门推荐上一条 /5 下一条

在线客服 快速回复 返回顶部 返回列表