Golang中如何实现仅执行一次的JavaScript代码
Golang中如何实现仅执行一次的JavaScript代码 传统方法可能是在每个页面上放置一段代码来检查 JavaScript 是否已加载:
window.onload = function () {
if (localStorage.getItem("hasCodeRunBefore") === null) {
//load code...
localStorage.setItem("hasCodeRunBefore", true);
}
}
是否有可能调用一个“隐藏”页面,无论怎样都只运行一次?类似于伪代码:
func init() {
tpl = template.Must(template.ParseGlob("public/tmpl/*.html"))
load code into site for every windows (store in localStorage)?
}
更多关于Golang中如何实现仅执行一次的JavaScript代码的实战教程也可以访问 https://www.itying.com/category-94-b0.html
3 回复
GonzaSaya: 使用 sync 包,你可以让某些代码只运行一次。
谢谢!但我该如何运行 JavaScript 并将其存储在 localStorage 中呢?
更多关于Golang中如何实现仅执行一次的JavaScript代码的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用 sync 包可以确保某些代码只执行一次:
sync package - sync - Go Packages
sync 包提供了基本的同步原语,例如互斥锁。
示例:
package main
import (
"fmt"
"sync"
)
func main() {
var once sync.Once
onceBody := func() {
fmt.Println("Only once")
}
done := make(chan bool)
for i := 0; i < 10; i++ {
go func() {
once.Do(onceBody)
done <- true
}()
}
for i := 0; i < 10; i++ {
<-done
}
}
在Go中实现JavaScript代码仅执行一次,通常需要结合前端技术。以下是几种实现方式:
1. 使用模板注入一次性脚本
在Go模板中注入一个只在首次加载时执行的脚本:
// main.go
package main
import (
"html/template"
"net/http"
)
var tpl *template.Template
var scriptInjected bool
func init() {
tpl = template.Must(template.ParseGlob("templates/*.html"))
}
func handler(w http.ResponseWriter, r *http.Request) {
data := struct {
InjectScript bool
}{
InjectScript: !scriptInjected,
}
if !scriptInjected {
scriptInjected = true
}
tpl.ExecuteTemplate(w, "index.html", data)
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
<!-- templates/index.html -->
<!DOCTYPE html>
<html>
<head>
<title>一次性脚本示例</title>
</head>
<body>
{{if .InjectScript}}
<script>
(function() {
if (!window.__hasInitialized) {
console.log("这段代码只执行一次");
// 你的初始化代码
window.__hasInitialized = true;
// 或者使用localStorage
if (!localStorage.getItem('appInitialized')) {
// 执行一次性操作
localStorage.setItem('appInitialized', 'true');
}
}
})();
</script>
{{end}}
<h1>页面内容</h1>
</body>
</html>
2. 使用Cookie控制脚本执行
// 设置一次性Cookie
func setOneTimeCookie(w http.ResponseWriter) bool {
cookie, err := r.Cookie("script_executed")
if err != nil {
// 设置Cookie,标记脚本已执行
http.SetCookie(w, &http.Cookie{
Name: "script_executed",
Value: "true",
Path: "/",
MaxAge: 31536000, // 一年
HttpOnly: false,
})
return true // 需要执行脚本
}
return false // 不需要执行脚本
}
// 在handler中使用
func handler(w http.ResponseWriter, r *http.Request) {
shouldExecute := setOneTimeCookie(w)
data := struct {
ExecuteScript bool
}{
ExecuteScript: shouldExecute,
}
tpl.ExecuteTemplate(w, "index.html", data)
}
3. 使用服务端Session控制
package main
import (
"github.com/gorilla/sessions"
"html/template"
"net/http"
)
var store = sessions.NewCookieStore([]byte("your-secret-key"))
var tpl *template.Template
func init() {
tpl = template.Must(template.ParseGlob("templates/*.html"))
}
func handler(w http.ResponseWriter, r *http.Request) {
session, _ := store.Get(r, "session-name")
var shouldExecute bool
if _, ok := session.Values["script_executed"]; !ok {
session.Values["script_executed"] = true
session.Save(r, w)
shouldExecute = true
}
data := struct {
ExecuteScript bool
}{
ExecuteScript: shouldExecute,
}
tpl.ExecuteTemplate(w, "index.html", data)
}
4. 纯前端解决方案(推荐)
如果不想依赖服务端状态,可以使用纯前端方案:
// 在模板中注入这个脚本
<script>
// 使用闭包确保只执行一次
var oneTimeExecution = (function() {
var executed = false;
return function() {
if (!executed) {
executed = true;
// 你的初始化代码
console.log("这段代码只执行一次");
// 或者使用更持久的方式
if (!window.oneTimeFlag) {
// 执行一次性操作
window.oneTimeFlag = true;
// 使用localStorage跨会话保持状态
if (!localStorage.getItem('appInitialized')) {
// 执行初始化
localStorage.setItem('appInitialized', 'true');
// 执行你的业务逻辑
initializeApp();
}
}
}
};
})();
// 在页面加载时调用
window.addEventListener('load', oneTimeExecution);
function initializeApp() {
// 你的初始化逻辑
console.log("应用初始化完成");
}
</script>
5. 结合Go和JavaScript的完整示例
// main.go
package main
import (
"html/template"
"net/http"
"time"
)
var tpl *template.Template
func init() {
funcMap := template.FuncMap{
"now": time.Now,
}
tpl = template.Must(template.New("").Funcs(funcMap).ParseGlob("templates/*.html"))
}
func handler(w http.ResponseWriter, r *http.Request) {
// 生成唯一的版本号或时间戳
version := time.Now().Unix()
data := struct {
Version int64
}{
Version: version,
}
tpl.ExecuteTemplate(w, "page.html", data)
}
<!-- templates/page.html -->
<!DOCTYPE html>
<html>
<head>
<title>一次性脚本</title>
<script>
// 使用版本控制
var currentVersion = {{.Version}};
if (localStorage.getItem('appVersion') !== currentVersion.toString()) {
// 版本变化,执行初始化
console.log("执行版本: " + currentVersion);
// 你的初始化代码
initializeApp();
// 更新存储的版本
localStorage.setItem('appVersion', currentVersion.toString());
}
function initializeApp() {
// 一次性初始化逻辑
console.log("应用初始化");
}
</script>
</head>
<body>
<h1>页面内容</h1>
</body>
</html>
这些方法可以根据你的具体需求选择使用。纯前端方案(使用localStorage)是最简单且不依赖服务端状态的方法,而结合Go的模板注入可以提供更精确的控制。

