Golang构建后如何自动刷新当前网页

Golang构建后如何自动刷新当前网页 我发现了这个库,它在开发过程中帮了我很多:

GitHub

GitHub

avatar

gravityblast/fresh

在保存/创建/删除源文件后构建并(重新)启动Go Web应用程序。- gravityblast/fresh

但我正在开发一个REST应用程序,每次文件更改时我都必须手动刷新当前网页。有没有可能在编译过程结束时自动重新加载当前页面?有没有类似fresh的库能够做到这一点?

谢谢。


更多关于Golang构建后如何自动刷新当前网页的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang构建后如何自动刷新当前网页的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go开发中实现自动刷新网页的需求,可以通过结合使用文件监控工具和浏览器自动刷新机制来实现。以下是几种实用的解决方案:

方案一:使用Air(推荐)

Air是Fresh的现代化替代品,配置更简单:

# 安装Air
go install github.com/cosmtrek/air@latest

# 在项目根目录创建.air.toml
cat > .air.toml << EOF
root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"

[build]
args_bin = []
cmd = "go build -o ./tmp/main ."
delay = 1000
exclude_dir = ["assets", "tmp", "vendor", "testdata"]
exclude_file = []
exclude_regex = ["_test.go"]
exclude_unchanged = false
follow_symlink = false
full_bin = ""
include_dir = []
include_ext = ["go", "tpl", "tmpl", "html"]
include_file = []
kill_delay = "0s"
log = "build-errors.log"
poll = false
poll_interval = 0
rerun = false
rerun_delay = 500
send_interrupt = false
stop_on_root = false

[color]
app = ""
build = "yellow"
main = "magenta"
runner = "green"
watcher = "cyan"

[log]
main_only = false
time = false

[misc]
clean_on_exit = false

[screen]
clear_on_rebuild = false
keep_scroll = true
EOF

# 运行Air
air

方案二:自定义解决方案(集成LiveReload)

创建带有LiveReload功能的自定义开发服务器:

package main

import (
    "fmt"
    "html/template"
    "log"
    "net/http"
    "os/exec"
    "time"
    
    "github.com/fsnotify/fsnotify"
)

const liveReloadScript = `
<script>
    const evtSource = new EventSource("/events");
    evtSource.onmessage = function(event) {
        if (event.data === "reload") {
            window.location.reload();
        }
    };
</script>
`

func main() {
    watcher, err := fsnotify.NewWatcher()
    if err != nil {
        log.Fatal(err)
    }
    defer watcher.Close()

    // 监控Go文件变化
    err = watcher.Add(".")
    if err != nil {
        log.Fatal(err)
    }

    // SSE端点用于推送重新加载事件
    http.HandleFunc("/events", func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "text/event-stream")
        w.Header().Set("Cache-Control", "no-cache")
        w.Header().Set("Connection", "keep-alive")
        w.Header().Set("Access-Control-Allow-Origin", "*")

        flusher, ok := w.(http.Flusher)
        if !ok {
            http.Error(w, "Streaming unsupported", http.StatusInternalServerError)
            return
        }

        // 保持连接打开
        for {
            select {
            case event := <-watcher.Events:
                if event.Op&fsnotify.Write == fsnotify.Write {
                    fmt.Fprintf(w, "data: reload\n\n")
                    flusher.Flush()
                    time.Sleep(100 * time.Millisecond)
                }
            case <-r.Context().Done():
                return
            }
        }
    })

    // 示例页面,包含LiveReload脚本
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        tmpl := template.Must(template.New("index").Parse(`
            <!DOCTYPE html>
            <html>
            <head>
                <title>Auto Reload Example</title>
            </head>
            <body>
                <h1>Go Auto Reload Demo</h1>
                <p>Last updated: {{.Time}}</p>
                {{.LiveReload}}
            </body>
            </html>
        `))
        
        data := struct {
            Time      string
            LiveReload template.HTML
        }{
            Time:      time.Now().Format("2006-01-02 15:04:05"),
            LiveReload: template.HTML(liveReloadScript),
        }
        
        tmpl.Execute(w, data)
    })

    log.Println("Server starting on :8080 with auto-reload")
    log.Fatal(http.ListenAndServe(":8080", nil))
}

方案三:使用goweb(集成方案)

goweb提供了完整的开发体验:

# 安装goweb
go install github.com/gowebapi/goweb@latest

# 在项目中使用
goweb run main.go

对应的Go代码示例:

package main

import (
    "net/http"
)

func main() {
    http.HandleFunc("/api/users", func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "application/json")
        w.Write([]byte(`{"users": [{"id": 1, "name": "John"}]}`))
    })

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte(`
            <!DOCTYPE html>
            <html>
            <head>
                <title>REST API with Auto Reload</title>
                <script src="/livereload.js"></script>
            </head>
            <body>
                <h1>REST API Development</h1>
                <button onclick="fetchUsers()">Load Users</button>
                <div id="output"></div>
                
                <script>
                    function fetchUsers() {
                        fetch('/api/users')
                            .then(response => response.json())
                            .then(data => {
                                document.getElementById('output').innerHTML = 
                                    JSON.stringify(data, null, 2);
                            });
                    }
                </script>
            </body>
            </html>
        `))
    })

    http.ListenAndServe(":3000", nil)
}

依赖安装

# 安装所需的包
go get github.com/fsnotify/fsnotify
go get github.com/cosmtrek/air

这些方案都能在文件更改时自动重新编译并刷新浏览器页面。Air是目前最流行的选择,提供了开箱即用的体验,而自定义方案则提供了更多的控制灵活性。

回到顶部