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.rhkb.cn/news/124569.html

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

相关文章

web端调用本地摄像头麦克风+WebRTC腾讯云,实现直播功能

目录 关于直播直播流程直播视频格式封装推流和拉流 获取摄像头和麦克风权限navigator.getUserMedia()MediaDevices.getUserMedia() WebRTC腾讯云快直播 关于直播 视频直播技术大全、直播架构、技术原理和实现思路方案整理 直播流程 视频采集端&#xff1a; 1、视频采集&#…

简述视频智能分析EasyCVR视频汇聚平台如何通过“AI+视频融合”技术规避八大特殊作业风险

视频智能分析EasyCVR视频汇聚平台可以根据不同的场景需求&#xff0c;让平台在内网、专网、VPN、广域网、互联网等各种环境下进行音视频的采集、接入与多端分发。在视频能力上&#xff0c;视频云存储平台EasyCVR可实现视频实时直播、云端录像、视频云存储、视频存储磁盘阵列、录…

uniapp 实现滑动元素删除效果

官网地址&#xff1a;uni-app官网 (dcloud.net.cn) 最终效果如下图&#xff1a; 滑动删除需要用到 uni-ui 的 uni-swipe-action 组件和 uni-swipe-action-item 属性名类型可选值默认值是否必填说明left-optionsArray/Object--否左侧选项内容及样式right-optionsArray/Object--…

Vue2+Vue3基础入门到实战项目(七)——智慧商城项目

Vue 核心技术与实战 智慧商城 接口文档&#xff1a;https://apifox.com/apidoc/shared-12ab6b18-adc2-444c-ad11-0e60f5693f66/doc-2221080 演示地址&#xff1a;http://cba.itlike.com/public/mweb/#/ 01. 项目功能演示 1.明确功能模块 启动准备好的代码&#xff0c;演示…

【Unity3D赛车游戏优化篇】【十】汽车粒子特效和引擎咆哮打造极速漂移

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…

【PHP代码审计】反序列化漏洞实战

文章目录 概述资源下载地址Typecho代码审计-漏洞原理call_user_func()_applyFilter()、get()与__get__toString()__construct()install.php POC利用漏洞利用复现利用链执行phpinfo()GET利用POST利用 getshell生成payload漏洞利用蚁剑连接 总结 概述 序列化&#xff0c;“将对象…

从Matrix-ResourceCanary看内存快照生成-ForkAnalyseProcessor(1)

前文看到AutoDumpProcessor的处理逻辑主要是生成&#xff0c;裁剪hprof文件并回调到PluginListener中&#xff0c;接下来我们来看下ForkAnalyseProcessor的处理逻辑。 ForkAnalyseProcessor public class ForkAnalyseProcessor extends BaseLeakProcessor {private static fi…

Nginx 本地部署服务

nginx 部署服务 一、下载二、解压三、文件替换四、浏览器中输入五、离线部署瓦片服务 一、下载 可以到官网下载&#xff0c;官方网址&#xff1a;https://nginx.org/也可以用我发的包 二、解压 三、文件替换 解压打开后文件&#xff0c;双击 nginx.exe 浏览器输入 localhost…

对极几何与三角化求3D空间坐标

一&#xff0c;使用对极几何约束求R,T 第一步&#xff1a;特征匹配。提取出有效的匹配点 void find_feature_matches(const Mat &img_1, const Mat &img_2,std::vector<KeyPoint> &keypoints_1,std::vector<KeyPoint> &keypoints_2,std::vector&l…

Python超入门(1)__迅速上手操作掌握Python

# 1.第一个代码&#xff1a;输出语句 # 1.第一个代码&#xff1a;输出语句 print("My dogs name is Huppy!") print(o----) print( ||| ) print("*" * 10) """ 输出结果&#xff1a; My dogs name is Huppy! o----||| ********** "&…

RK3588算法盒子maskrom模式下系统烧录

先在firefly官网下载bulidroot文件&#xff0c;然后进行烧录相关文件。 点击upgrade&#xff0c;进行烧录升级&#xff1b; 等待烧录完成后&#xff0c; 重新开机进入loader模式下&#xff0c; 进行烧录Untunt20.04系统的操作就行。

(16)线程的实例认识:Await,Async,ConfigureAwait

继续(15)的例子 一、ConfigureAwait()的作用 private async void BtnAsync_Click(object sender, EventArgs e)//异步{Stopwatch sw Stopwatch.StartNew();TxtInfo.Clear();AppendLine("异步检索开始...");AppendLine($"当前线程Id:{Environment.CurrentManage…

springboot使用切面记录接口访问日志

前言 当我们开发和维护一个复杂的应用程序时&#xff0c;了解应用程序的运行情况变得至关重要。特别是在生产环境中&#xff0c;我们需要追踪应用程序的各个方面&#xff0c;以确保它正常运行并能够及时发现潜在的问题。其中之一关键的方面是记录应用程序的接口访问日志。 Sp…

函数相关概念

4.函数 1.函数的概念 1.什么是函数? 把特点的代码片段,抽取成为独立运行的实体 2.使用函数的好处1.重复使用,提供效率2.提高代码的可读性3.有利用程序的维护 3.函数的分类1.内置函数(系统函数)已经提高的alert(); prompt();confirm();print()document.write(),console.log()…

http和https区别,第三方证书如何保证服务器可信

目录 HTTP和HTTPS有以下区别&#xff1a; 第三方证书如何保证服务器的可信性 需要注意哪些方面 可能遇到什么问题 随着互联网技术的不断发展&#xff0c;数据传输的安全性越来越受到人们的关注。HTTP和HTTPS是两种常用的网络协议&#xff0c;它们之间的主要区别在于数据传输…

【图文并茂】c++介绍之队列

1.1队列的定义 队列&#xff08;queue&#xff09;简称队&#xff0c;它也是一种操作受限的线性表&#xff0c;其限制为仅允许在表的一端进行插入操作&#xff0c;而在表的另一端进行删除操作 一些基础概念&#xff1a; 队尾&#xff08;rear&#xff09; &#xff1a;进行插…

CloudQuery X PolarDB:让数据库管理更简单

前言&#xff1a;8 月 15 日&#xff0c;CloudQuery 数据操作管控平台与阿里云 PolarDB 数据库管理软件&#xff0c;完成产品集成认证测试。也在以下功能上完善了用户使用 PolarDB 的体验&#xff0c;使数据库的管理更加安全高效。 支持在 CloudQuery 中创建连接&#xff0c;便…

数据接口工程对接BI可视化大屏(一)

文章目录 第1章 案例概述1.1 案例目标1.2 BI最终效果1.2.1 PC端显示效果1.2.2 移动端显示效果 后记 第1章 案例概述 1.1 案例目标 此项目以常见的手机零售BI场景为例&#xff0c;介绍如何编写数据接口工程对接BI可视化大屏。 如何从当前常见的主流大数据场景中为后台程序推送…

数据结构入门-13-图

文章目录 一、图的概述1.1 图论的作用1.2 图的分类1.2.1 无向图1.2.2 有向图1.2.3 无权图1.2.4 有劝图 1.3 图的基本概念 二、树的基本表示2.1 邻接矩阵2.1.1 邻接矩阵 表示图2.1.2 邻接矩阵的复杂度 2.2 邻接表2.2.1 邻接表的复杂度2.2.2 邻接表By哈希表 三、图的深度优先遍历…

sentinel加密狗使用及规则配置

Sentinel加密狗是一种硬件加密设备&#xff0c;用于保护软件应用程序免受未经授权的访问和复制。它可以提供软件许可管理、访问控制和数据保护等功能。下面是Sentinel加密狗的使用及规则配置的相关介绍。 Sentinel加密狗的使用 插入加密狗&#xff1a;将Sentinel加密狗插入计算…