go语言学习之使用 Go 标准库构建 Web 应用程序

我爱海鲸 2024-09-03 23:18:15 go语言学习

简介Handler、请求、静态资源的部署

1、使用ide创建一个go项目

安装go的http库

 go get net/http

2、编写相关代码main.go:

代码如下:

package main

import "net/http"

func main() {
	http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
		writer.Write([]byte("Hell World"))
	})

	http.ListenAndServe("localhost:8080", nil) // DefaultServeMux 简单理解为路由
}

然后点击运行,直接访问 localhost:8080 即可

3、如何处理(Handler)请求:

少废话,直接上代码:

package main

import "net/http"

type helloHandler struct{}

func (m *helloHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Hello!"))
}

type aboutHandler struct{}

func (m *aboutHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("About!"))
}

func welcome(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Welcome!"))
}

func main() {
	mh := helloHandler{}
	a := aboutHandler{}

	server := http.Server{
		Addr:    "localhost:8080",
		Handler: nil,
	}

	http.Handle("/hello", &mh)
	http.Handle("/about", &a)
	http.HandleFunc("/home", func(writer http.ResponseWriter, request *http.Request) {
		writer.Write([]byte("Home!"))
	})
	http.HandleFunc("/welcome", welcome)

	server.ListenAndServe()
}

4、内置Handler

go语言提供了五个内置的Handler

NotFoundHandler

RedirectHandler

StripPrefix

TimeoutHandler

FileHandler

1)http.NotFoundHandler

func NotFoundHandler() Handler
返回一个 handler,它给每个请求的响应都是“404 page not found”

2)http.RedirectHandler

func RedirectHandler(url string, code int) Handler
返回一个 handler,它把每个请求使用给定的状态码跳转到指定的URL.
 url,要跳转到的URL
code,跳转的状态码( 3xx),常见的: StatusMovedPermanently、StatusFound或StatusSeeOther 等

3)http.StripPrefix

func StripPrefix(prefix string, h handler) Handler
返回一个handler,它从请求URL中去掉指定的前缀,然后再调用另一个handler。
·如果请求的URL与提供的前缀不符,那么404

略像中间件

prefix,URL将要被移除的字符串前缀
h,是一个 handler,在移除字符串前缀之后,这个 handler将会接收到请求修饰了另一个 Handler

4)http.TimeoutHandler

func TimeoutHandler(h Handler, dt time.Duration, msg string)Handler
返回一个handler,它用来在指定时间内运行传入的h。

也相当于是一个修饰器
h,将要被修饰的handler
dt,第一个 handler 允许的处理时间
msg,如果超时,那么就把msg返回给请求,表示响应时间过长

5)http.FileHandler

func FileServer(root FileSystem) Handler
返回一个handler,使用基于root的文件系统来响应请求

type FileSystem interface {
	Open(name string) (File, error)
}

使用时需要用到操作系统的文件系统,所以还需要委托给:

type Dir string
func (d Dir) Open(name string) (File, error)

下面我们来通过FileHandler来完成一个访问html静态页面的实例

源码:

package main

import "net/http"

func main() {
	http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
		http.ServeFile(writer, request, "wwwhaijin"+request.URL.Path)
	})
	http.ListenAndServe(":8080", nil)
}

我们在项目中创建了一个wwwhaijin的文件夹,然后写入了一段html代码,启动项目,直接访问localhost:8080,发现就能够直接访问到了

我们在把上面的代码优化一下:

package main

import "net/http"

func main() {
	http.ListenAndServe(":8080", http.FileServer(http.Dir("wwwhaijin")))
}

2024-06-03 start:

静态资源的部署:

package main

import (
    "net/http"
    "strings"
)

// handleCORS 处理CORS的中间件
func handleCORS(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        if strings.HasPrefix(r.URL.Path, "/api/") {
            origin := r.Header.Get("Origin")
            if origin != "" {
                w.Header().Set("Access-Control-Allow-Origin", origin)
                w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
                w.Header().Set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization")
                w.Header().Set("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Cache-Control, Content-Language, Content-Type")
                w.Header().Set("Access-Control-Allow-Credentials", "false")
                w.Header().Set("content-type", "application/json")
            }

            if r.Method == http.MethodOptions {
                w.WriteHeader(http.StatusOK)
                return
            }
        }
        next.ServeHTTP(w, r)
    })
}

// noCacheMiddleware 禁用缓存的中间件
func noCacheMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Cache-Control", "no-store")
        next.ServeHTTP(w, r)
    })
}

func main() {
    // 静态文件目录
    fs := http.FileServer(http.Dir("./static"))

    // 禁用缓存的中间件
    noCacheFs := noCacheMiddleware(fs)

    // 将静态文件目录处理为根路径
    http.Handle("/", noCacheFs)

    // API路由
    apiHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Hello, this is an API response!"))
    })
    http.Handle("/api/", handleCORS(apiHandler))

    // 启动服务器
    http.ListenAndServe(":8894", nil)
}

end

2024-09-03 start:

GoLang | 1.16 新增的 (embed ) 应场景 - Gin 打包vue3静态资源二进制文件中 embed 方式 - 《Gin》 - 极客文档 (geekdaxue.co)

end

你好:我的2025