传统 Web 基础操作:Go 模版引擎的极简入门指南

传统 Web 基础操作:Go 模版引擎的极简入门指南

Web操作

单控制器和多控制器

单控制器
type MyHandle struct{}func(m *MyHandle)ServeHTTP(w http.ResponseWriter, r *http.Request){ fmt.Fprint(w,"返回的数据哈哈")//相当于w.Write([]byte("返回的数据哈哈"))}funcmain(){ h := MyHandle{} server := http.Server{Addr:":8090", Handler:&h} server.ListenAndServe()//相当于http.ListenAndServe(":8090", &h)}
多控制器

在实际开发中,大部分情况不应该只有一个控制器,不同的请求应该交给不同的处理单元,在golang中支持两种多处理方式

  • 多个处理器(Handle)
  • 多个处理函数(HandleFunc)
1、多处理器

即使用http.Handle把不同的URL绑定到不同的处理器中

type MyHandle struct{}type MyOtherHandle struct{}func(m *MyHandle)ServeHTTP(w http.ResponseWriter, r *http.Request){ fmt.Fprint(w,"返回的数据哈哈")//相当于w.Write([]byte("返回的数据哈哈"))}func(m *MyOtherHandle)ServeHTTP(w http.ResponseWriter, r *http.Request){ fmt.Fprint(w,"返回的数据哈哈")//相当于w.Write([]byte("返回的数据哈哈"))}funcmain(){ h := MyHandle{} h2 := MyOtherHandle{} http.Handle("/a",&h) http.Handle("/abc",&h2) http.ListenAndServe(":8090",nil)}
2、多处理函数

把不同的URL绑定到不同的函数上

funcfirst(w http.ResponseWriter, r *http.Request){ fmt.Fprint(w,"多处理函数--first")//相当于w.Write([]byte("返回的数据哈哈"))}funcsecond(w http.ResponseWriter, r *http.Request){ fmt.Fprint(w,"多处理函数--second")//相当于w.Write([]byte("返回的数据哈哈"))}funcmain(){ http.HandleFunc("/f", first) http.HandleFunc("/s", second) http.ListenAndServe(":8090",nil)}

获取请求头和获取请求参数

1、获取请求头
funcnow(w http.ResponseWriter, r *http.Request){ h := r.Header fmt.Println(h) fmt.Println(h["Accept-Encoding"]) fmt.Println(len(h["Accept-Encoding"]))}funcmain(){ http.HandleFunc("/now", now) http.ListenAndServe(":9090",nil)}
2、获取请求参数
funcnow(w http.ResponseWriter, r *http.Request){ r.ParseForm()//必须先解析成Form,否则无数据 fmt.Println(r.Form) fmt.Println(r.Form["url_long"]) fmt.Println(r.Form["url_long"][0])}funcmain(){ http.HandleFunc("/now", now) http.ListenAndServe(":9090",nil)}
3、验证表单的输入
//验证手机号//使用MatchString函数和正则表达式//其他一些字符串都可以这样判断if m,_:= regexp.MatchString(`^(1[3|4|5|8][0-9]\d{4,8})$`, r.Form.Get("mobile"));!m {returnfalse}

Web项目结构

--项目名 --src --static --css --images --js --view --index.html --main.go

HTML模版和静态资源显示

1、HTML模版显示

Go语言标准库中html/template包提供了html模版支持,把HTML当作模版可以在访问控制器显示HTML模版信息

使用template.ParseFiles()可以解析多个模版文件

funcwelcome(w http.ResponseWriter, r *http.Request){ t,_:= template.ParseFiles("view/index.html") t.Execute(w,nil)}funcmain(){ http.HandleFunc("/", welcome) http.ListenAndServe(":9090",nil)}

目录结构

在这里插入图片描述
2、静态资源显示

把静态资源文件放到特定的文件夹中,使用Go语言的文件服务就可以进行加载

funcwelcome(w http.ResponseWriter, r *http.Request){ t,_:= template.ParseFiles("view/index.html") t.Execute(w,nil)}funcmain(){ http.HandleFunc("/", welcome) http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static")))) http.ListenAndServe(":9090",nil)}

目录结构

在这里插入图片描述

向模版中传递数据和调用函数

一、向模版中传递数据
  • 可以在HTML中使用{{}}获取template.Execute()第二个参数传递的值
  • 最常用的{{.}}中的".“是指针,指向当前变量,成为"dot”
1、字符串类型
funcwelcome(w http.ResponseWriter, r *http.Request){ t,_:= template.ParseFiles("view/index.html") t.Execute(w,"smallming")}funcmain(){ http.HandleFunc("/", welcome) http.ListenAndServe(":9090",nil)}
<body><pre> 尊敬的{{.}}先生/女士 您已经被我公司录取。 </pre></body>
2、结构体类型
type User struct{ Name string Age int}funcwelcome(w http.ResponseWriter, r *http.Request){ t,_:= template.ParseFiles("view/index.html") t.Execute(w, User{"张三",19})}funcmain(){ http.HandleFunc("/", welcome) http.ListenAndServe(":9090",nil)}
<body><pre> 姓名:{{.Name}}<br/> 年龄:{{.Age}} </pre></body>

PS:结构体的字段一定要首字母大写,否则模版访问不到。

3、map类型
type User struct{ Name string Age int}funcwelcome(w http.ResponseWriter, r *http.Request){ t,_:= template.ParseFiles("view/index.html") m :=make(map[string]interface{}) m["user"]= User{"张三",19} m["money"]=1000 t.Execute(w, m)}funcmain(){ http.HandleFunc("/", welcome) http.ListenAndServe(":9090",nil)}
<body><pre> 姓名:{{.user.Name}}<br/> 年龄:{{.user.Age}}<br/> 工资:{{.money}} </pre></body>
二、在模版中调用函数
1、调用系统函数
funcwelcome(w http.ResponseWriter, r *http.Request){ t,_:= template.ParseFiles("view/index.html") time1 := time.Now() t.Execute(w, time1)}funcmain(){ http.HandleFunc("/", welcome) http.ListenAndServe(":9090",nil)}
<body><pre> 完整时间:{{.}} 年:{{.Year}} 月:{{.Month}} 日:{{.Day}} 格式化时间:{{.Format "2006-01-02 15:04:05"}} </pre></body>
2、调用自定义函数

如果希望调用自定义函数,需要借助html/template包下的FuncMap进行映射。

函数被添加映射后,只能通过函数在FuncMap中的key调用函数。

funcMyFormat(t time.Time)string{return t.Format("2006-01-02 15:04:05")}funcwelcome(w http.ResponseWriter, r *http.Request){//将自定义函数绑定到map上 fm := template.FuncMap{"mf": MyFormat}//新建一个空模版,将函数绑定到该模版 t := template.New("index.html").Funcs(fm)//把我们的html解析到该空模版上 t,_= t.ParseFiles("view/index.html") time1 := time.Now() t.Execute(w, time1)}funcmain(){ http.HandleFunc("/", welcome) http.ListenAndServe(":9090",nil)}
<body><pre> 完整时间:{{.}} 调用格式化函数:{{mf .}} </pre></body>

模版使用if、range等

1、二元比较运算函数
eq <=>== ne <=>!= lt <=>< le <=><= gt <=>> ge <=>>=
2、if语句
<body> 取出数据{{.}}<br/> {{if .}} 执行了if {{else}} 执行了else {{end}}<br/> html模版信息 </body>
<body> {{$n:=123}} {{if gt $n 456}} 执行if {{else}} 执行else {{end}} </body>
3、range的使用
<body> {{.}}<br/> {{range .}} {{.}}<br/> {{end}} </body>

模版嵌套

  • 在实际项目中常常出现页面复用的情况,例如:整个网站的头部信息和底部信息复用
  • 可以使用动作{{template “模版名称”}}来引用模版
  • 引用的模版必须在HTML中定义这个模版

定义名称

{{define "模版名称"}} html {{end}} 

示例:

{{define "head"}} <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>Title</title></head><body> head.html {{.}} </body></html> {{end}} 
{{define "foot"}} <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>Title</title></head><body> foot.html {{.}} </body></html> {{end}} 
{{define "layout"}} <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>Title</title><scripttype="text/javascript"src="/static/js/index.js"></script></head><body> {{/*引用head模版*/}} {{template "head" "head的参数"}}<br/> 中间内容<br/> {{template "foot" "head的参数"}} </body></html> {{end}} 

在go中需要加载所有文件再选定主模版

funcwelcome(w http.ResponseWriter, r *http.Request){//解析所有文件 t, err := template.ParseFiles("view/index.gohtml","view/head.gohtml","view/foot.gohtml")if err !=nil{ log.Printf("err:%v", err)}//选定主模版layout t.ExecuteTemplate(w,"layout",nil)}funcmain(){ http.HandleFunc("/", welcome) http.ListenAndServe(":9090",nil)}

文件上传

文件中ioutil包已经弃用,这里使用io包和os包

<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>文件上传</title></head><body><formaction="upload"method="post"enctype="multipart/form-data"> 文件名:<inputtype="test"name="name"/><br/> 文件:<inputtype="file"name="file"/><br/><inputtype="submit"value="提交"/></form></body></html>
<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>文件上传</title></head><body> 文件上传成功 </body></html>
funcwelcome(w http.ResponseWriter, r *http.Request){ t,_:= template.ParseFiles("view/filetest.gohtml") t.Execute(w,nil)}funcupload(w http.ResponseWriter, r *http.Request){//从表单中获取名为"name"的值 fileName := r.FormValue("name")//从表单中获取名为"file"的文件字段//file是文件句柄//fileHeader是文件的元信息,包括文件名、大小等 file, fileHeader,_:= r.FormFile("file")//读取文件中的内容 b,_:= io.ReadAll(file) os.WriteFile("D:/"+fileName+fileHeader.Filename[strings.LastIndex(fileHeader.Filename,"."):], b,0777) t,_:= template.ParseFiles("view/success.gohtml") t.Execute(w,nil)}funcmain(){ http.HandleFunc("/", welcome) http.HandleFunc("/upload", upload) http.ListenAndServe(":9090",nil)}

文件下载

<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>文件上传</title></head><body><ahref="download?filename=abc.png">下载</a></body></html>
funcdownload(w http.ResponseWriter, r *http.Request){//从表单中获取文件名称 filename := r.FormValue("filename")//根据路径去找文件 f, err := os.ReadFile("D:/"+ filename)if err !=nil{ fmt.Fprintln(w,"文件下载失败", err)return} h := w.Header()//设置相应内容的MIME类型魏二进制流//设置为文件处理,而不是直接显示 h.Set("Content-Type","application/octet-stream")//attachment设置内容处置方式为附件下载//filename="..."指定下载时的默认文件名filename h.Set("Content-Disposition","attachment;filename="+filename)//将文件内容写入http响应体发送 w.Write(f)}

Read more

Flutter for OpenHarmony:Flutter 三方库 postgrest — 鸿蒙端直接访问 PostgreSQL 数据库的极速连接器

Flutter for OpenHarmony:Flutter 三方库 postgrest — 鸿蒙端直接访问 PostgreSQL 数据库的极速连接器

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net 前言 在开发 Flutter for OpenHarmony 应用时,传统的“端-接口-数据库”模式往往显得过于沉重。 如果只是为了实现基础的增删改查,却需要编写大量的后端 API 逻辑、处理复杂的 SQL 拼写以及繁琐的 JSON 打包,这不仅增加了开发成本,也导致系统在面对业务变动时极其脆弱。 postgrest 正是解决这一痛点的利器。它是专门为 PostgREST(一个能将 PostgreSQL 数据库直接转换为 RESTful API 的高性能网关)打造的 Dart 客户端驱动。通过它,开发者可以在鸿蒙端以类似于编写 SQL 的语义,直接完成对云端数据库的高级检索与操作。 今天,我们将深入探讨如何利用该库在鸿蒙平台上实现“零接口开发”的数据交互体验。 一、原理解析 / 概念介绍

By Ne0inhk
Flutter 三方库 flad_cli 的鸿蒙化适配指南 - 实现 Dart 工程的自适应模板扫描与脚手架自动化、支持端侧资源一键生成与代码架构规约校验实战

Flutter 三方库 flad_cli 的鸿蒙化适配指南 - 实现 Dart 工程的自适应模板扫描与脚手架自动化、支持端侧资源一键生成与代码架构规约校验实战

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 flad_cli 的鸿蒙化适配指南 - 实现 Dart 工程的自适应模板扫描与脚手架自动化、支持端侧资源一键生成与代码架构规约校验实战 前言 在进行 Flutter for OpenHarmony 的企业级项目矩阵开发时,如何保证上百个模块的目录结构、基础依赖、甚至是 import 规约保持高度一致?手动复制粘贴模板显然不可持续。flad_cli 是一个专为 Dart 项目设计的极简脚手架(Scaffold)命令行工具。它能根据预设规则自动生成或扫描工程文件。本文将探讨如何在鸿蒙端利用此工具构建极致的工业化开发流水线。 一、原直观解析 / 概念介绍 1.1 基础原理 flad_cli 建立在“代码生成(Code Gen)”与“扫描(

By Ne0inhk
Actix-web 性能优化技巧:从原理到实践

Actix-web 性能优化技巧:从原理到实践

引言 Actix-web 作为 Rust 生态中性能最优秀的 Web 框架之一,其设计充分利用了 Rust 的零成本抽象和 Actor 模型的优势。然而,即使使用如此高性能的框架,不当的使用方式仍然会导致性能瓶颈。本文将深入探讨 Actix-web 的性能优化技巧,从底层原理出发,结合实际案例展示如何充分释放框架潜力。 核心优化原理 Actix-web 的性能优势源于其异步运行时和工作线程池的精心设计。它使用 Tokio 作为异步运行时,采用多线程模型处理请求。理解这一点对于优化至关重要:每个工作线程都有自己的 event loop,阻塞操作会直接影响该线程处理其他请求的能力。 性能优化的第一要务是避免在异步上下文中执行阻塞操作。常见的陷阱包括同步数据库查询、文件 I/O、CPU 密集型计算等。这些操作应该被妥善处理,要么使用异步版本,要么转移到专门的线程池中执行。 实践一:连接池优化 数据库连接是 Web 应用中最常见的性能瓶颈。合理配置连接池参数能显著提升吞吐量: useactix_web:

By Ne0inhk

前端大屏可视化自适应怎么做,零基础入门到精通,收藏这篇就够了

前端数据大屏自适应设计方案全解析 在前端数据大屏的开发中,自适应设计是关键环节,它能确保大屏在不同设备和屏幕尺寸上都能呈现出良好的视觉效果和交互体验。除了常见的 transform: scale、rem/vw、Flex/Grid 等方案外,还有其他有效的方法可以实现自适应。下面为您详细介绍这些方案及其优缺点,以便您根据项目需求做出合适的选择。 一、多种自适应方案详解 (一)transform: scale 整体缩放方案 此方案的原理是先按照特定的设计稿尺寸(如 1920×1080)完成页面容器的开发,在运行时通过 transform: scale() 对整个页面进行缩放操作,从而使其适配不同的屏幕尺寸。 优点: 1. 实现过程简单快捷,能够迅速适配各种分辨率的屏幕,大大缩短开发周期。 2. 无需对原有的页面布局和样式进行大规模修改,减少了开发工作量。 缺点: 1. 缩放后,页面元素可能会出现模糊的情况,影响整体的视觉质量和用户体验。 2. 鼠标事件的坐标与实际视觉位置不一致,容易导致点击偏移问题,影响交互的准确性。 3. 在某些浏览器中,

By Ne0inhk