首页 > 其他分享 >GO web学习(二)

GO web学习(二)

时间:2023-05-19 11:33:49浏览次数:43  
标签:web 函数 学习 html ResponseWriter template GO 引擎 模板

跟着b站https://space.bilibili.com/361469957 杨旭老师学习做的笔记

Response响应

ResponseWriter

包括Writer,WriterHeader,Header

  • 从服务器向客户端返回响应需要使用 ResponseWriter
  • ResponseWriter 是一个接口,handler 用它来返回响应
  • 真正支撑 ResponseWriter 的幕后 struct 是非导出的 http.response
// w http.ResponseWriter, r *http.Request
// 其实 w 也是个指针,按引用传递

写入到 ResponseWriter

  • Write 方法接收一个 byte 切片作为参数,然后把它写入到 HTTP 响应的 Body 里面。
  • 如果在 Write 方法被调用时,header 里面没有设定 content type,那么数据的前 512 字节就会被用来检测 content type
  • 默认WriteHeader 是200 OK
str:=`<html>
	<head><title>Go web</title></head>
	<body><h1>hello World</h1></body>
	</html>`
w.Write([]byte(str))

WriteHeader 方法

  • WriteHeader 方法接收一个整数类型(HTTP 状态码)作为参数,并把它作为 HTTP 响应的状态码返回
  • 如果该方法没有显式调用,那么在第一次调用 Write 方法前,会隐式的调用 WriteHeader(http.StatusOK)
  • 所以 WriteHeader 主要用来发送错误类的 HTTP 状态码
  • 调用完 WriteHeader 方法之后,仍然可以写入到 ResponseWriter,但无法再修改 header 了

w.Header().Set("Location","http://google.com")
// 这个也是个重定向法子
w.WriteHeader(302)

Header 方法

Header方法返回 headers的map,可以进行修改。
修改后的headers将会体现在返回给客户端的HTTP响应里

// 结构体就类似于json的对象
// 这里是整了个结构体,转换成json格式了
type Post struct{
  User string
  Threads []string
}
func jsonExample(w http.ResponseWriter, r *http.Request){
w.Header().Set("Content-Type","application/json")
post:= &Post{
   User: "timer",
   Threads: []string{"first","second","third"},
}
json,_ := json.Marshal(post)
w.Write(json)
}

内置的 Response


NotFound 函数,
包装一个404码和一个额外信息

ServeFile 函数
从文件系统提供文件,返回给请求者

ServeContent 
它可以把实现了io,ReadSeeker接口的人员内容返回给请求者。
还可以处理 Range 请求(范围请求),如果只请求了资源的一部分内容,
那么 ServeContent 就可以如此响应。
而 ServeFile 或 io.Copy 则不行。

Redirect 
重定向

模板

模板的主要内容
简介 模板引擎 Action
参数、变量、管道 函数 模板组合

什么是模板?

  • Web 模板就是预先设计好的 HTML 页面,它可以被模板引擎反复的使用,来产生 HTML 页面
  • Go 的标准库提供了 text/template,html/template 两个模板库。text这个是任意格式文档,html这个是HTML格式专用
    • 大多数 Go 的 Web 框架都使用这些库作为 默认的模板引擎

模板与模板引擎

模板和数据经过模板引擎 产生最终展示的HTML网页,写入到ResponseWriter中。

两种理想的模板引擎

无逻辑模板引擎

  • 通过占位符,动态数据被替换到模板中
  • 不做任何逻辑处理,只做字符串替换
  • 处理完全由 handler 来完成
  • 目标是展示层和逻辑的完全分离

逻辑嵌入模板引擎

  • 编程语言被嵌入到模板中
  • 在运行时由模板引擎来执行,也包含替换功能
  • 功能强大
  • 逻辑代码遍布 handler 和 模板,难以维护

Go 的模板引擎

  • 主要使用的是 text/template,HTML 相关的部分使用了 html/template,是个混合体。
  • 模板可以完全无逻辑,但又具有足够的嵌入特性
  • 和大多数模板引擎一样,Go Web 的模板位于无逻辑和嵌入逻辑之间的某个地方

GO模板引擎的工作原理

  • 在 Web 应用中,通常是由 handler 来触发模板引擎

  • handler 调用模板引擎,并将使用的模板传递给引擎

    • 通常是一组模板文件和动态数据
  • 模板引擎生成 HTML,并将其写入到 ResponseWriter

  • ResponseWriter 再将它加入到 HTTP 响应中,返回给客户端

关于模板

  • 模板必须是可读的文本格式,扩展名任意。对于 Web 应用通常就是 HTML
    里面会内嵌一些命令(叫做 action)
  • text/template 是通用模板引擎
  • html/template 是 HTML 模板引擎
  • action 位于双层花括号之间:{{ . }}
    • 这里的 . 就是一个 action
    • 它可以命令模板引擎将其替换成一个值

一个模板的例子

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Go Web Programming</title>
  </head>
  <body>
    {{ . }}
  </body>
</html>

使用模板引擎

  • 解析模板源(可以是字符串或模板文件),从而创建一个解析好的模板结构
  • 执行解析好的模板,并传入 ResponseWriter 和 数据。
    • 这会触发模板引擎组合解析好的模板和数据,来产生最终的 HTML,并将它传递给 ResponseWriter

解析模板

ParseFiles
ParseGlob
Parse
解析其实就是进行语法分析

ParseFiles

  • 解析模板文件,并创建一个解析好的模板 结构,后续可以被执行
  • ParseFiles 函数是 Template struct 上 ParseFiles 方法的简便调用
  • 调用 ParseFiles 后,会创建一个新的模板,模板的名字是文件名
  • New 函数
  • ParseFiles 的参数数量可变,但只返回一个模板
  • 当解析多个文件时,第一个文件作为返回的模板(名、内容),其余的作为 map,供后续执行使用
//解析单个文件
t,_ := template.ParseFiles("wwwroot/tmpl.html")
t.Execute(w,"helloWorld")
//解析多个文件
ts,_ := template.ParseFiles("wwwroot/tmpl.html","wwwroot/index.html")
ts.ExecuteTemplate(w,"wwwroot/index.html","this is a index html")
// new函数  t1和t2等价
//t1
t,_:=template.ParseFiles("tmpl.html")
//t2
t:= template.New("tmpl.html")
t,_= t.ParseFiles("tmpl.html")

ParseGlob

对匹配给定模式的所有文件进行语法分析

t,_ := template.ParseGlob("*.html")

Parse

可以解析字符串模板,其它方式最终都会调用 Parse

t:=template.New("tmpl.html")
t,_= t.Parse(tmplhtmlStr)
t.Execute(w,参数)

LookUp方法

通过模板名来寻找模板,如果没找到就返回 nil

func loadTemplates() *template.Template{
result:= template.New("templates")
template.Must(result.ParseGlob("templates/*.html"))
return result
}
func lookUp(){
templates := loadTemplates()
http.HandleFunc("/",func(w http.ResponseWriter, r *http.Request) {
fileName :=r.URL.Path[1:]
// 找模板
t := templates.Lookup(fileName)
//如果找到的模板不为空
if t !=  nil {
err :=t.Execute(w,nil)
  if err !=nil{
	log.Fatalln(err.Error())
  }
}
})
}

Must 函数

  • 可以包裹一个函数,返回到一个模板的指针 和 一个错误。
    • 如果错误不为 nil,那么就 panic
//用Must函数包裹函数,
// 来处理万一没找模板发生错误的情况
t:=template.Must(t.ParseFiles("tmpl.html"))

执行模板

Execute

参数是 ResponseWriter、数据
适用于单模板
模板集:只用第一个模板

ExecuteTemplate

参数是:ResponseWriter、模板名、数据
适用于模板集合

注意
都只能输入一个数据,这个数据是个接口,什么类型都可以。可以输入一个结构体,有字段,有方法。

模板 - Action

什么是 Action

  • Action 就是 Go 模板中嵌入的命令,位于两组花括号之间 {{ xxx }}
  • 就是一个 Action,而且是最重要的一个。它代表了传入模板的数据
  • Action 主要可以分为五类:
    • 条件类
    • 迭代/遍历类
    • 设置类
    • 包含类
    • 定义类

条件类

 {{ if arg }}     
 some content        
 {{ end }} 

 {{ if arg }}
 some content
 {{ else }}
   other content
 {{ end }}

迭代/遍历类

  • 用来遍历数组,slice map 或者 channel等
{{ range array}}
	dot is set to the element {{ . }}
{{ else }}
	no thing to show
{{ end }}

{{range $key ,$value := . }}
the key is {{$key}} and the value  is {{$value}}
{{end}}

迭代循环中的{{ . }}代表的是当前被迭代的元素
回落机制,当传入的东西为空时,启用else

设置类

它允许在指定范围内,让“.”来表示其它指定的值(arg)
也有回落机制

{{ with MySetArg }}
 dot is set to {{ . }}
{{ end }}	

{{ with MySetArg }}
 dot is set to {{ . }}
{{ else }}
//当 MySetArg 自己设置值是空值时,还是用原来的参数
 the dot is still {{ . }}
{{ end }}

包含类

嵌套模板执行时建议使用ExecuteTemplate

{{ template "name" }}
它允许你在模板中包含其它的模板

{{ template "name" arg }}
给被包含模板传递参数

向被包含的模板传参,传的 是 . 的话,
就是把包含模板的参数传进去了

定义类

define action

Layout

layout模板就是网页中固定的部分,它可以被多个网页重复使用
Include(包含)action 的形式:{{ template "name" . }}以这种方式做 layout 模板是不可行的。
正确的做法是在模板文件里面使用 define action 再定义一个模板。

同一模板文件里可以定义多个不同的模板
不同模板文件里可以定义同名模板

<!-- 定义模板 -->
{{ define "layout"}}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- Font Awesome -->
<link
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"
rel="stylesheet"
/>
<!-- Google Fonts -->
<link
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
rel="stylesheet"
/>
<!-- MDB -->
<link
href="https://cdnjs.cloudflare.com/ajax/libs/mdb-ui-kit/6.2.0/mdb.min.css"
rel="stylesheet"
/>
</head>
<body>
    <nav class="navbar">
         <a href="#" class="navbar-brand">这是个可复用组件 </a>
    </nav>
    <!-- 包含模板 -->
    {{template "content" . }}
    
</body>
<!-- MDB -->
<script
  type="text/javascript"
  src="https://cdnjs.cloudflare.com/ajax/libs/mdb-ui-kit/6.2.0/mdb.min.js"
></script>
</html>
{{ end }}

block 块动作

如果一个模板中包含{{template "content"}}这个模板,如果你解析的时候没有传入content模板,程序就会崩溃。所以添加默认模板
{{ block "content" . }}
some thing
{{ end }}
假如没有传入content模板,就会启用block定义的默认模板,程序可以继续执行

参数、函数和管道

参数

  • 参数就是模板里面用到的值。
    • 可以是 bool、整数、string …
    • 也可以是 struct、struct 的字段、数组的 key 等等
  • 参数可以是变量、方法(返回单个值或返回一个值和一个错误)或函数
  • 参数可以是一个点“.”,也就是传入模板引擎的那个值。

记得大写首字母!!!

在 Action 中设置变量

可以在 action 中设置变量,变量以 $ 开头:
$variable := value
一个迭代 action 的例子:

{{ range $key, $value := . }}
  The key is {{ $key }} and the value is {{ $value }}
{{ end }}

逻辑运算符

eq 等于 / ne 不等于
lt 小于/ gt 大于
le 小于等于 / ge 大于等于
and 和
or 或
not 非

if eq . "hello"
如果传入参数和hello相等

管道

  • 管道是按顺序连接到一起的参数、函数和方法。
    • 和 Unix 的管道类似
  • 例如:{{ p1 | p2 | p3 }}
    • p1、p2、p3 要么是参数,要么是函数
  • 管道允许我们把参数的输出发给下一个参数,下一个参数由管道(|)分隔开。
{{ 12.345 | printf "%.2f" }}

{{ . | turnDouble | printf "%.2f"}}

函数

自定义函数

  • 参数可以是一个函数
  • Go 模板引擎提供了一些基本的内置函数,功能比较有限。例如 fmt.Sprint 的各类变体等
  • 开发者可以自定义函数:
    • 可以接收任意数量的输入参数
    • 返回:
      一个值
      一个值+一个错误

内置函数

  • define、template、block
  • html、js、urlquery。对字符串进行转义,防止安全问题
    • 如果是 Web 模板,那么不会需要经常使用这些函数。
  • index
  • print/printf/println
  • len
  • with

如何自定义函数

template.Funcs(funcMap FuncMap) *Template
type FuncMap map[string]interface{}
value 是函数
可以有任意数量的参数
返回单个值的函数或返回一个值+一个错误的函数

  • 创建一个 FuncMap(map 类型)。
    • key 是函数名
    • value 就是函数
  • 把 FuncMap 附加到模板
func divfunc(w http.ResponseWriter,r * http.Request){
funcMap := template.FuncMap{"fdate":formDate}
t:=template.New("test.html").Funcs(funcMap)
t.ParseFiles("test.html")
t.Execute(w,time.Now())
}
func formDate(timer time.Time) string{
layout :="2006-01-02"
return timer.Format(layout)
}

html那边

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    {{ . | fdate}}
    或者
    {{ fdate . }}
</body>
</html>
  • 常见用法:template.New(“”).Funcs(funcMap).Parse(…)

    • 调用顺序非常重要
  • 可以在管道中使用

  • 也可以作为正常函数使用

  • 管道更强大且灵活

标签:web,函数,学习,html,ResponseWriter,template,GO,引擎,模板
From: https://www.cnblogs.com/tiangong/p/17414413.html

相关文章

  • golang 内存 stats 字段解释
    字段解释样例Alloc当前堆中已经分配给对象使用所占用的空间字节数322952TotalAlloc累计堆中已经分配给对象使用所占用的空间字节数,只会增长,不会减少29511472Sys总共从OS申请的字节数,包含运行时的heap、stack和其他内部数据结构的总和,它是虚拟内存空间。不一......
  • Restful和WebService区别
    简介Restful是一种架构风格,其核心是面向资源,更简单;而webService底层SOAP协议,主要核心是面向活动;两个都是通过web请求调用接口RESTful是什么REST就是(REpresentationalStateTransfer单词太长记不住就对了)是一种构架风格,REST指的是一组架构约束条件和原则。满足这些约......
  • DHub Superworks自动化学习项目图纸
    分享一套 Superworks自动化设计项目图纸,包括封面,图纸目录,高层代号位置代号,原理图22张,部件汇总表,元件列表,连接列表,接线图,端子列表。下载以后打开swPro文件以打开整个项目。没有安装Superworks自动化设计的朋友可根据项目包中的readme文件安装。......
  • C#中的Task.CompletedTask和Task.Result学习
    在学习C#中的Task方法时,可以知道Task启动一个异步线程方法可以用Task.Run()进行,具体可以参看博客 https://www.cnblogs.com/yaosj/p/10342883.html和 https://www.cnblogs.com/wynblogscc/p/15138423.html但是,在有些返回类型是Task的方法中,可以在不进行异步的情况下计算结果.......
  • go install
    在命令行中,可以使用"goinstall"命令编译并安装一个Go程序。这个命令将会编译指定的Go程序文件,并将生成的可执行文件安装到$GOPATH/bin目录下。例如,如果你想安装main.go文件中的程序,可以在命令行中输入:goinstallmain.go这个命令会编译main.go文件中的代码,并将生成的可执行......
  • MySQL学习基础篇Day4
    CREATEUSER'用户名'@'主机名'IDENTIFIEDBY'密码';2.7DCLDCL英文全称是DataControlLanguage(数据控制语言),用来管理数据库用户、控制数据库的访问权限。2.7.1管理用户1).查询用户select*frommysql.user; 查询的结果如下:其中Host代表当前用户访问的主机,......
  • Web笔记
    WEBvue组件全局组件在main.js中注册//引入组件importTypeNavfrom'@/components/TypeNav'//第一个参数:全局组件的名字第二个参数:哪一个组件Vue.component(TypeNav.name,TypeNav)使用:无需引入,直接使用标签<TypeNav/>节流和防抖lodash节流:在规定的间隔时......
  • CTF 在线平台 WEBwp
    1.web_Unagi知识点,xxe编码绕过这道题看到uplaod里面的example,很明显就是xxe了,提示是把/flag读出来。 第四个页面告诉我们flag在/flag中发现上传的是xml,于是自己构造1.xml 这是我们平常用的xxe,但是这个提示是被过滤了,构造完了之后上传发现被WAF拦截了 这里通过XX......
  • JAVA学习之枚举类和注解
    之后的知识点都是一些小的细的碎的知识点的大杂烩,于是就选择每天都建一个新博客,去记录知识点了。枚举简单介绍:1.枚举对应英文(enumeration,简称enum)。2.枚举是一组常量的集合。3.可以理解为:枚举是一种特殊的类,里面只包含一组有限的特定的对象。首先尝试用已有知识解决需求:自......
  • Golang -embed结合viper打包静态文件
    代码含有viper独立方式和goembed方式packagemainimport("bytes""embed""fmt""time""github.com/spf13/viper")//go:embedconfig.yamlvarf[]bytefuncmain(){//config:=viper.New()......