Web framework-Gin(二)

目录

一、Gin

1、Ajax

2、文件上传

2.1、form表单中文件上传(单个文件)

2.2、form表单中文件上传(多个文件)

2.3、ajax上传单个文件

2.4、ajax上传多个文件

3、模板语法

4、数据绑定

5、路由组

6、中间件


一、Gin

1、Ajax

        AJAX 即“Asynchronous Javascript And XML”(异步 JavaScript和 XML),是指一种创建交互式、快速动态网页应用的网页开发技术,无需重新加载整个网页的情况下,能够更新部分网页的技术。通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

        AJAX的最大的特点: 异步访问,局部刷新。

案例:Ajax之验证用户名是否被占用

main.go

func main() {r := gin.Default()r.LoadHTMLGlob("part02/templates/**/*")//指定js文件:r.Static("/s", "part02/static")r.GET("/test1", myfunc.Test1)r.POST("/getUserInfo", myfunc.Test2)r.POST("/ajaxpost", myfunc.Test3)r.Run()
}

myfunc.go

func Test1(context *gin.Context) {context.HTML(200, "demo01/hello01.html", nil)
}func Test3(context *gin.Context) {//获取post-ajax请求的数据,获取对应的参数:uname := context.PostForm("uname")fmt.Println(uname)fmt.Println(uname == "丽丽")if uname == "丽丽" {context.JSON(200, gin.H{"msg": "用户名重复了!",})} else {context.JSON(200, gin.H{"msg": "",})}
}

hello01.html  注意:引入jQuery.min.js

{{define "demo01/hello01.html"}}
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><link rel="stylesheet" href="/s/css/mycss.css"><script src="/s/js/jQuery.min.js"></script>
</head>
<body>用户form表单<br><form action="/getUserInfo" method="post">用户名:<input type="text" name="username" id="uname"><span id="errmsg"></span><br>密码:<input type="password" name="pwd"><input type="submit" value="提交"></form><script>//获取用户名的文本框var unametext = document.getElementById("uname");//给文本框绑定一个事件:失去焦点的时候会触发后面的函数的事件unametext.onblur = function () {//获取文本框的内容:var uname = unametext.value;//alert(uname)可以弹出数据,验证代码的正确性//局部刷新:通过ajax技术来实现数据的校验 ---》 后台 :异步访问,局部刷新//调用ajax方法需要传入json格式的数据: $.ajax({属性名:属性值,属性名:属性值,方法名:方法})$.ajax({url : "/ajaxpost",//请求路由type : "POST",//请求类型 GET、POSTdata : {//向后端发送的数据,以json格式向后传递"uname" : uname},success : function (info) {//后台响应成功会调用函数,info-后台响应的数据封装到info中,info名字可以随便起document.getElementById("errmsg").innerText = info["msg"]},fail : function () {后台响应失败会调用函数}})}</script>
</body>
</html>
{{end}}

测试:

2、文件上传

2.1、form表单中文件上传(单个文件)

main.go

func main() {r := gin.Default()r.LoadHTMLGlob("part03/templates/**/*")r.GET("/userindex", myfunc.Test1)r.POST("/savefile", myfunc.Test2)r.Run()
}

myfunc.go

func Test1(context *gin.Context) {context.HTML(200, "demo01/hello01.html", nil)
}func Test2(context *gin.Context) {//获取前端传入的文件:file, _ := context.FormFile("myfile")fmt.Println(file.Filename)//加入一个时间戳:time_int := time.Now().Unix()time_str := strconv.FormatInt(time_int, 10) //10:十进制//保存在我的本地:context.SaveUploadedFile(file, "e://"+time_str+file.Filename)//响应一个字符串:context.String(200, "文件上传成功")
}

hello01.html 

{{define "demo01/hello01.html"}}
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><link rel="stylesheet" href="/s/css/mycss.css">
</head>
<body>用户form表单<br><form action="/savefile" method="post" enctype="multipart/form-data"><input type="file" name="myfile"><input type="submit" value="提交"></form>
</body>
</html>
{{end}}

测试:

2.2、form表单中文件上传(多个文件)

main.go

func main() {r := gin.Default()r.LoadHTMLGlob("part03/templates/**/*")r.GET("/userindex", myfunc.Test1)r.POST("/savefile", myfunc.Test3)r.Run()
}

myfunc.go

func Test3(context *gin.Context) {//先获取form表单form, _ := context.MultipartForm()//在form表单中获取name相同的文件:files := form.File["myfile"] //File是个Map,通过key获取value部分//files就是name相同的多个文件:挨个处理---遍历处理:for _, file := range files {//加入一个时间戳:time_int := time.Now().Unix()time_str := strconv.FormatInt(time_int, 10) //10:十进制//保存在我的本地:context.SaveUploadedFile(file, "e://"+time_str+file.Filename)}//响应一个字符串:context.String(200, "文件上传成功")
}

hello01.html 

{{define "demo01/hello01.html"}}
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><link rel="stylesheet" href="/s/css/mycss.css">
</head>
<body>用户form表单<br><form action="/savefile" method="post" enctype="multipart/form-data"><input type="file" name="myfile"><input type="file" name="myfile"><input type="file" name="myfile"><input type="submit" value="提交"></form>
</body>
</html>
{{end}}

测试:

2.3、ajax上传单个文件

注意利用ajax上传文件的话,在ajax中需要加两个参数:
(1)contentType:false
默认为true,当设置为true的时候,jquery ajax 提交的时候不会序列化 data,而是直接使用data
(2)processData:false,
目的是防止上传文件中出现分界符导致服务器无法正确识别文件起始位置。

main.go

func main() {r := gin.Default()r.LoadHTMLGlob("part04/templates/**/*")r.Static("/s", "part04/static")r.GET("/userindex", myfunc.Test1)r.POST("/savefile", myfunc.Test4)r.Run()
}
myfunc.go
func Test4(context *gin.Context) {//获取前端传入的文件:file, _ := context.FormFile("file")fmt.Println(file.Filename)//加入一个时间戳:time_int := time.Now().Unix()time_str := strconv.FormatInt(time_int, 10) //10:十进制//保存在我的本地:context.SaveUploadedFile(file, "e://"+time_str+file.Filename)//响应一个字符串:context.String(200, "文件上传成功")
}

hello01.html 

{{define "demo01/hello01.html"}}
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="/s/js/jQuery.min.js"></script>
</head>
<body>用户form表单<br><form action="/savefile" method="post"><input type="file" class="myfile" multiple="multiple"><input type="button" value="提交按钮" id="btn"></form><script>//获取按钮var btn = document.getElementById("btn");//给按钮加入一个单击事件:btn.onclick = function () {//创建存放form表单的数据:var form_data = new FormData();//在form_data添加要传入到后台的元素:form_data.append("file",$(".myfile")[0].files[0])//利用ajax向后台传递数据:$.ajax({url : "/savefile",type : "POST",data : form_data,contentType:false,processData:false,success : function () {}})}</script>
</body>
</html>
{{end}}

2.4、ajax上传多个文件

main.go

func main() {r := gin.Default()r.LoadHTMLGlob("part04/templates/**/*")r.Static("/s", "part04/static")r.GET("/userindex", myfunc.Test1)r.POST("/savefile", myfunc.Test5)r.Run()
}

myfunc.go

func Test5(context *gin.Context) {//先获取form表单form, _ := context.MultipartForm()//在form表单中获取name相同的文件:files := form.File["myfile"] //File是个Map,通过key获取value部分//files就是name相同的多个文件:挨个处理---遍历处理:for _, file := range files {//加入一个时间戳:time_int := time.Now().Unix()time_str := strconv.FormatInt(time_int, 10) //10:十进制//保存在我的本地:context.SaveUploadedFile(file, "e://"+time_str+file.Filename)}//响应一个字符串:context.String(200, "文件上传成功")
}

hello01.html 

{{define "demo01/hello01.html"}}
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="/s/js/jQuery.min.js"></script>
</head>
<body>用户form表单<br><form action="/savefile" method="post"><input type="file" class="myfile"><input type="file" class="myfile"><input type="file" class="myfile"><input type="button" value="提交按钮" id="btn"></form><script>//获取按钮var btn = document.getElementById("btn");//给按钮加入一个单击事件:btn.onclick = function () {//创建存放form表单的数据:var form_data = new FormData();//获取多个文件:var myfiles = $(".myfile");//对多个文件进行遍历,每一个添加到form_data中去:for (var i = 0;i < myfiles.length;i++){form_data.append("myfile",myfiles[i].files[0]);}//利用ajax向后台传递数据:$.ajax({url : "/savefile",type : "POST",data : form_data,contentType:false,processData:false,success : function () {}})}</script>
</body>
</html>
{{end}}

响应重定向:是请求服务器后,服务器通知浏览器,让浏览器去自主请求其他资源的一种方式。

3、模板语法

【1】模板
在写动态页面的网站的时候,我们常常将不变的部分提出成为模板,可变部分通过后端程序的渲染来生成动态网页,golang也支持模板渲染。
【2】模板内内嵌的语法支持,全部需要加  {{}}  来标记。
【3】在模板文件内, . 代表了当前位置的上下文:
        (1)在非循环体内,. 就代表了后端传过来的上下文
        (2)在循环体中,. 就代表了循环的上下文
【4】在模板文件内, $  代表了模板根级的上下文
【5】在模板文件内, $. 代表了模板根级的上下文

【6】字符串:{{ “abc,Hello World ” }}
【7】原始字符串:{{ `abc` }}    {{ `a` }}    不会转义
【8】字节类型:{{ ' a' }} ---> 97  会转义
【9】打印:
打印字符串: {{ print "Hello World" }}
nil类型:{{ print nil }} 

{{define "demo01/hello.html"}}
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>打印字符串: {{ print "Hello World" }}nil类型:{{ print nil }} 变量的定义:{{$name := "XIAOMING"}}变量的使用:{{$name}}
</body>
</html>
{{end}}

【10】if:

方式1:
{{if .condition}}
{{end}}
方式2:
{{if .condition1}}
{{else}}
{{end}}
方式3:
{{if .condition1}}
{{else if .contition2}}
{{end}}内置的模板函数
not 非
and 与
or 或
eq 等于
ne 不等于
lt 小于 (less than)
le 小于等于
gt 大于
ge 大于等于

【11】range循环

    {{range .arr}}{{.}}{{$.age}}{{end}}<br>{{range $i,$v := .arr}}{{$i}}{{$v}}{{end}}

【12】with 关键字

{{ with pipeline }} T1 {{ end }}
{{ with pipeline }} T1 {{ else }} T0 {{ end }}
其中 pipeline 为判断条件,如满足就将 . 设为 pipeline 的值并执行 T1,不修改外面的 . 。
否则执行 T0。
{{define "demo01/hello.html"}}
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><br>获取结构体中内容:{{.stu.Age}}{{.stu.Name}}<br>启动with关键字:{{with .stu}}{{.Age}}{{.Name}}{{else}}暂无数据{{end}}
</body>
</html>
{{end}}

【13】template:作用:引入另一个模板文件

{{template "模板名" pipeline}}
PS:管道(传递数据的)
PS:引入的模板文件中也要用{ {define "路径"} } { {end} }包含
PS:如果想在引入的模板中也需要获取动态数据,必须使用 . 访问当前位置的上下文

hello.html

{{define "demo01/hello.html"}}
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><br>内嵌另外模板:{{/*    如果想要传递内容到内嵌模板中,可以通过.上下文进行传递,和内嵌页面共享上下文数据*/}}{{template "templates/demo01/hello2.html" .}}
</body>
</html>
{{end}}

hello2.html

{{define "templates/demo01/hello2.html"}}
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>这是一个内嵌页面。。。{{with .stu}}{{.Age}}{{.Name}}{{else}}暂无数据{{end}}
</body>
</html>
{{end}}

模板函数

【1】print     打印字符串
【2】printf    按照格式化的字符串输出
格式:参照:Go中:fmt.Sprintf
【3】len  返回对应类型的长度(map, slice, array, string, chan)
【4】管道传递符:   |  
函数中使用管道传递过来的数值 
【5】括号提高优先级别:()
【6】and  只要有一个为空,则整体为空;如果都不为空,则返回最后一个
【7】or  只要有一个不为空,则返回第一个不为空的;如果都是空,则返回空
【8】not 用于判断返回布尔值,如果有值则返回false,没有值则返回true
【9】index  读取指定类型对应下标的值(map, slice, array, string)
【10】eq:等于equal,返回布尔值
【11】ne:不等于 not equal,返回布尔值
【12】lt:小于 less than,返回布尔值
【13】le:小于等于less equal,返回布尔值
【14】gt:大于 greater than,返回布尔值
【15】ge:大于等于 greater equal,返回布尔值
【16】日期格式化  Format
实现了时间的格式化,返回字符串,设置时间格式比较特殊,需要固定方式,不能轻易改变
【17】自定义模板函数:

【17】自定义模板函数:

myfunc.go

// 定义一个函数:
func Add(num1 int, num2 int) int {return num1 + num2
}

main.go注册函数

import ("github.com/gin-gonic/gin""html/template""test_gin/part05/myfunc"
)func main() {r := gin.Default()//注册函数:FuncMap是html/FuncMapr.SetFuncMap(template.FuncMap{//键值对的作用:key指定前端调用的名字,value指定的是后端对应的函数"add": myfunc.Add,})r.LoadHTMLGlob("part05/templates/**/*")r.Static("/s", "part05/static")r.GET("/test1", myfunc.Test1)r.Run()
}

hello01.html使用函数

{{define "demo01/hello01.html"}}
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<br>调用add函数:{{add 11 82}}
</body>
</html>
{{end}}

测试:

4、数据绑定

数据绑定:能够基于请求自动提取JSON、form表单和QueryString类型的数据,并把值绑定到后端指定的结构体对象中去

5、路由组

路由组:将不同的路由按照版本、模块进行不同的分组,利于维护,方便管理。

6、中间件

        Gin框架允许开发者在处理请求的过程中,加入用户自己的钩子(Hook)函数(中间件函数),这个钩子函数就叫中间件。
        中间件适合处理一些公共的业务逻辑,比如登录认证、权限校验、数据分页、记录日志、耗时统计等等。

Web framework-Gin

Go framework-Beego

难留少年时,总有少年来!

无论你是年轻还是年长,所有程序员都需要记住:时刻努力学习新技术,否则就会被时代抛弃!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/102160.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据库 范式化和反范式化

第一范式 1NF 主要确保数据表中每个字段的值必须具有原子性&#xff0c;也就是说数据表中每个字段的值为不可再次拆分的最小数据单元 第二范式 2NF 在满足第一范式的基础上&#xff0c;还要满足数据表里的每一条数据记录&#xff0c;都是可唯一标识的&#xff0c;而且所有非…

使用半导体材料制作霍尔元件的优点

霍尔元件是一种基于霍尔效应的传感器&#xff0c;可以测量磁场强度和电流等物理量。霍尔效应是指&#xff0c;当电流通过一块导体时&#xff0c;如果该导体置于垂直于电流方向的磁场中&#xff0c;就会在导体两侧出现一定的电势差&#xff0c;这就是霍尔效应。霍尔元件可以利用…

C++-map和set

本期我们来学习map和set 目录 关联式容器 键值对 pair 树形结构的关联式容器 set multiset map multimap 关联式容器 我们已经接触过 STL 中的部分容器&#xff0c;比如&#xff1a; vector 、 list 、 deque 、forward_list(C11)等&#xff0c;这些容器统称为序列式…

【Rust】001-基础语法:变量声明及数据类型

【Rust】001-基础语法&#xff1a;变量声明及数据类型 文章目录 【Rust】001-基础语法&#xff1a;变量声明及数据类型一、概述1、学习起源2、依托课程 二、入门程序1、Hello World2、交互程序代码演示执行结果 3、继续上难度&#xff1a;访问链接并打印响应依赖代码执行命令 三…

《Java程序设计》实验报告

实验内容&#xff1a;面向对象程序设计 1、定一个名为Person的类&#xff0c;其中含有一个String类型的成员变量name和一个int类型的成员变量age&#xff0c; 分别为这两个变量定义访问方法和修改方法&#xff0c;另外再为该类定义一个名为speak的方法&#xff0c; 在其中输出n…

role、user、schema在Oracle、MySQL、PostgreSQL的区别

0.先上结论 数据库逻辑可以细分为&#xff1a;角色、用户、数据库、模式PostgreSQL和MySQL合并了角色和用户&#xff0c;MySQL还合并了数据库、模式Oracle合并了用户、数据库、模式 1.图 1.1.架构 1.2.用户和角色 1.2.1.PostgreSQL 1.2.2.MySQL 1.2.3.Oracle 参考文章 数据…

MATLAB创建avi文件

简介 MATLAB可以对音频和视频文件进行处理&#xff0c;这里简单说明一下MATLAB创建avi文件的用法。 常用函数 aviinfo 测试用用例&#xff0c;如下所示 用于avi格式的音频视频文件&#xff0c;返回一个对该文件的描述&#xff0c;只能用于avi格式的音频视频文件。 仔细看…

E. Nastya and Potions

Problem - E - Codeforces 思路&#xff1a;想到用图论前驱图了&#xff0c;但是因为考虑可能有环的存在&#xff0c;但是其实题干中说明了不能通过一种或几种混合得到自己&#xff0c;所以就保证了不存在环&#xff0c;那就能用拓扑结构的性质做&#xff0c;用记忆化搜索就可以…

Linux之SELinux

目录 概述 定义 作用 SELinux与传统的权限区别 SELinux工作原理 名词解释 主体&#xff08;Subject&#xff09; 目标&#xff08;Object&#xff09; 策略&#xff08;Policy&#xff09; 安全上下文&#xff08;Security Context&#xff09; 文件安全上下文查看 …

华为数通方向HCIP-DataCom H12-821题库(单选题:321-340)

第321题 BGP的Open报文是用于建立对等体连接的,以下哪一项不属于Open报文中携带的参数信息? A、发送者的Router ID B、AS号 C、BGP版本号 D、TCP端口号 答案:D 解析:以下是BGP的Open报文: 第322题 在建立BGP对等体的过程中,OpenSent状态表明BGP等待的Open报文 并对收…

介绍PHP

PHP是一种流行的服务器端编程语言&#xff0c;用于开发Web应用程序。它是一种开源的编程语言&#xff0c;具有易学易用的语法和强大的功能。PHP支持在服务器上运行的动态网页和Web应用程序的快速开发。 PHP可以与HTML标记语言结合使用&#xff0c;从而能够生成动态的Web页面&a…

CSS笔记(黑马程序员pink老师前端)选择器,字体,文本属性,Emmet语法,元素显示模式,CSS背景

选择器 选择器分为基础选择器和复合选择器两大类。 基础选择器 包括:标签选择器、类选择器、id选择器和通配符选择器。 /*标签选择器 */p {color: red;}/*类选择器 */.classname {color: yellow;}/*id选择器 */#idname {color: blue;}/*通配符选择器&#xff0c;选择页面所有的…