The gin framework in Go language [upload files-multiple files] + cookie settings (9)

Problem uploading multiple images in the files field?

 

html page

{
   
   {define "admin/register/index.html"}}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>admin/register/index.html</title>
</head>
<body>
    <form action="/admin/register/edit" method="post" enctype="multipart/form-data">

        用户名:<input type="text" name="username" id="username">

        <br>
        
        头像: <input type="file" name="files" id="files" multiple> 
 
        <input type="submit" value="提交">
    </form>
</body>
</html>


{
   
   {end}}

Routing file: adminRouters.go

package routers

import (
	"project/controllers/admins"

	"github.com/gin-gonic/gin"
)

func AdminRoutersInit(r *gin.Engine) {
	adminRouter := r.Group("/admin")
	{
		//
		adminRouter.GET("/", admins.AdminControllers{}.Index)

		// 登录
		adminRouter.GET("/index", admins.AdminControllers{}.PageIndex)
		adminRouter.POST("/login", admins.AdminControllers{}.Login)

		// 注册页面  上传多文件 multiple
		adminRouter.GET("/register", admins.AdminControllers{}.Register)
		adminRouter.POST("/register/edit", admins.AdminControllers{}.Edit)

		// 展示页面
		adminRouter.GET("/views", admins.AdminControllers{}.Views)

	}
}

controllers controller code adminControllers.go:

package admins

import (
	"fmt"
	"net/http"
	"os"
	"path"
	"project/models"
	"strconv"

	"github.com/gin-gonic/gin"
)

type AdminControllers struct{}

func (con AdminControllers) Index(c *gin.Context) {
	c.String(200, "admin后管项目")
}

func (con AdminControllers) PageIndex(c *gin.Context) {
	c.HTML(200, "admin/login/index.html", gin.H{
		"title": "admin后管项目",
	})
}

func (con AdminControllers) Login(c *gin.Context) {

	username := c.PostForm("username")
	password := c.PostForm("password")

	c.String(200, "用户名:=%v,密码:=%v \n", username, password)

	// c.HTML(200, "admin/views/index.html", gin.H{
	// 	"title": "viewAdmin页面",
	// })

}

func (con AdminControllers) Register(c *gin.Context) {
	c.HTML(200, "admin/register/index.html", gin.H{
		"title": "注册页面",
	})
}

func (con AdminControllers) Edit(c *gin.Context) {

	username := c.PostForm("username")

	fmt.Printf("username==%v \n", username)

	//1. html 页面有   multiple属性时候   头像: <input type="file" name="files" id="files" multiple>   通过 multipartform 获取上传文件form,         
     err := c.MultipartForm()
     if err != nil {
	 	c.String(http.StatusBadRequest, "get form err: %s", err.Error())
	 	return
	 }
	 files := form.File["files"]
	 // 当前时间获取
	 for _, file := range files {
	 	// fmt.Println("==========path=%v \n", file.Filename)
	 	filename := filepath.Base(file.Filename)
	 	// fmt.Println("===========%v \n", filename)
 	    dst := path.Join("./static/upload", filename)
	 	if err := c.SaveUploadedFile(file, dst); err != nil {
	 		c.String(http.StatusBadRequest, "upload file err: %s", err.Error())
	 		return
	 	}
	}

}

The above is the code part about multi-file upload through the multiple attribute input tag.

In addition, when storing files on the local server, we need to distinguish a large number of pictures or files before storing them. Grouping storage facilitates subsequent query of files; here we can group files and store them in date format * timestamp format.

Here are some changes to the code:

package admins

import (
	"fmt"
	"net/http"
	"os"
	"path"
	"project/models"
	"strconv"

	"github.com/gin-gonic/gin"
)

type AdminControllers struct{}

func (con AdminControllers) Index(c *gin.Context) {
	c.String(200, "admin后管项目")
}

func (con AdminControllers) PageIndex(c *gin.Context) {
	c.HTML(200, "admin/login/index.html", gin.H{
		"title": "admin后管项目",
	})
}

func (con AdminControllers) Login(c *gin.Context) {

	username := c.PostForm("username")
	password := c.PostForm("password")

	c.String(200, "用户名:=%v,密码:=%v \n", username, password)

	// c.HTML(200, "admin/views/index.html", gin.H{
	// 	"title": "viewAdmin页面",
	// })

}

func (con AdminControllers) Register(c *gin.Context) {
	c.HTML(200, "admin/register/index.html", gin.H{
		"title": "注册页面",
	})
}

func (con AdminControllers) Edit(c *gin.Context) {

	username := c.PostForm("username")

	fmt.Printf("username==%v \n", username)

	//1. 获取上传文件
	file, err := c.FormFile("file")

	if err == nil {
		// 2. 获取文件后缀,判断是否类型正确 .png,.jpg,.gif,.jpeg,.png

		extName := path.Ext(file.Filename)

		allowExtMap := map[string]bool{
			".jpg":  true,
			".gif":  true,
			".png":  true,
			".jpeg": true,
		}

		if _, ok := allowExtMap[extName]; !ok {
			// c.Redirect() // 也可以跳转
			c.String(200, "上传的文件类型不合法")
			return
		}

		// 创建图片保存目录 、static/upload/20230630
		dayNum := models.GetDay()

		dir := path.Join("./static/upload", dayNum)

		err := os.MkdirAll(dir, 0666)
		if err != nil {
			fmt.Println(err)
			c.String(200, "MkdirAll失败")
			return
		}
		// 生成文件名称 和 文件保存的 目录
		// unix := models.GetUnix()
		// // unix + extName = filename
		// filename := strconv.FormatInt(unix, 10) + extName
		// 合并成一句
		filename := strconv.FormatInt(models.GetUnix(), 10) + extName

		// 执行上传
		dst := path.Join(dir, filename)
		c.SaveUploadedFile(file, dst)
	}


}

func (con AdminControllers) Views(c *gin.Context) {

	c.SetCookie("username", "王二妹", 3600, "/", "localhost", false, true)

	// c.String(200, "Views页面")
	c.HTML(http.StatusOK, "admin/views/index.html", gin.H{
		"title": "views页面",
	})
}

c.FormFile("file") It is a method used in the gin framework to obtain a single file upload . It receives one parameter as the file upload form field name and returns an  *multipart.FileHeader object and a possible error.

func uploadFile(c *gin.Context) {
    // 获取上传的文件
    file, err := c.FormFile("file")
    if err != nil {
        // 错误处理逻辑
    }

    // 处理文件
    // 保存文件到指定的路径
    err = c.SaveUploadedFile(file, "上传目录/"+file.Filename)
    if err != nil {
        // 错误处理逻辑
    }

    // 其他逻辑
}

In this example, the uploaded filec.FormFile("file")  will be retrieved based on the form field name  . If the file does not exist or an error occurs, the appropriate error will be returned."file" 

Then, you can further process the file according to actual needs, such as saving it to a specified path.

It should be noted that this method can only obtain the status of a single file upload. If you need to process multiple file uploads with the same name, you can use the method mentioned earlier . I won’t go into too much detail here about whether to upload multiple files or a single file (if you have any questions, you can leave a message). c.Request.MultipartForm.File 

Regarding the use of ctx.setCookie()...

In the Gin framework, use ctx.SetCookie()methods to set cookies. The following is a specific implementation example:

func setCookie(c *gin.Context) {
    // 设置Cookie的参数和值
    c.SetCookie("my_cookie", "example value", 3600, "/", "localhost", false, true)
    
    // 其他逻辑
}

In this example, we use c.SetCookie()the method to set the cookie. The parameters received by the method are as follows:

  • The first parameter is the name of the cookie.
  • The second parameter is the value of the cookie.
  • The third parameter is the cookie expiration time in seconds. In this example, set the cookie expiration time to 3600 seconds (i.e. 1 hour).
  • The fourth parameter is the path of the cookie, specifying the path where the cookie is available. In this example, we set it to the root path "/".
  • The fifth parameter is the domain of the cookie, specifying the domain name where the cookie is available. In this example, we set it to "localhost", which means it can only be used in the local test environment.
  • The sixth parameter is a Boolean value indicating whether to use HTTPS to send cookies. In this example we set it to false.
  • The seventh parameter is a Boolean value indicating whether the SameSite attribute is enabled. In this example we set it to true.

With this setting, the cookie can be sent to the client in the response, and the client will automatically store it and send it back to the server in subsequent requests.

func (con AdminControllers) Views(c *gin.Context) {

	c.SetCookie("username", "王二妹", 3600, "/", "localhost", false, true)

	// c.String(200, "Views页面")
	c.HTML(http.StatusOK, "admin/views/index.html", gin.H{
		"title": "views页面",
	})
}

方法接收的参数如下:

第一个参数是Cookie的名称。
第二个参数是Cookie的值。
第三个参数是Cookie的过期时间(以秒为单位)。在这个例子中,设置Cookie的过期时间为3600秒(即1小时)。
第四个参数是Cookie的路径,指定Cookie可用的路径。在这个例子中,我们将其设置为根路径 “/”。
第五个参数是Cookie的域,指定Cookie可用的域名。在这个例子中,我们将其设置为 “localhost”,表示只能在本地测试环境使用。
第六个参数是一个布尔值,指示是否使用HTTPS发送Cookie。在这个例子中,我们将其设置为false。
第七个参数是一个布尔值,指示是否启用SameSite属性。在这个例子中,我们将其设置为true。

It's important to note that this is just a simple example. In actual applications, you may need to make more detailed settings as needed, such as setting the cookie expiration time, domain name, Secure tag, etc. In addition, the Gin framework also provides c.SetSameSite()methods for setting SameSite properties and c.SetCookieOptions()for setting Cookie properties in more detail.

Regarding the expiration time of cookies:

The set time seconds value is an integer greater than 0: it represents the expiration time in seconds and will automatically expire and be cleared by the browser.

The set time seconds value is an integer less than 0: it means it has expired, and it can also be used as a program to delete the delete cookie.

 

I hope this article is helpful to your study!

Guess you like

Origin blog.csdn.net/A_LWIEUI_Learn/article/details/131483155