Golang中如何实现服务器响应的双重返回
Golang中如何实现服务器响应的双重返回 尝试构建一个支持多语言的简单Web应用程序,但我注意到输出语句中的内容被打印了两次:
func index(w http.ResponseWriter, r *http.Request) {
fmt.Println(lang.Value)
fmt.Println(cfg.Database.Username)
}
我得到的输出是:
D:\Development\GO\i18n>go run hasan/web
Listening to port: 8090
en
admin
en
admin
我的完整代码如下:
// main.go
package main
import (
"fmt"
"net/http"
"os"
"text/template"
"gopkg.in/yaml.v2"
)
// Config ...
type Config struct {
Server struct {
Port string `yaml:"port"`
Host string `yaml:"host"`
} `yaml:"server"`
Database struct {
Username string `yaml:"user"`
Password string `yaml:"pass"`
} `yaml:"database"`
}
func processError(err error) {
fmt.Println(err)
os.Exit(2)
}
func readFile(cfg *Config, lang string) {
f, err := os.Open(fmt.Sprint("configuration/", lang, ".yml"))
if err != nil {
processError(err)
}
defer f.Close()
decoder := yaml.NewDecoder(f)
err = decoder.Decode(cfg)
if err != nil {
processError(err)
}
}
func index(w http.ResponseWriter, r *http.Request) {
var tmpl *template.Template
var cfg Config
lang, err := r.Cookie("language")
if err != nil {
readFile(&cfg, "en")
tmpl, _ = template.New("").ParseFiles(fmt.Sprint("templates/en/page-en.html"), "base.html")
} else {
readFile(&cfg, lang.Value)
fmt.Println(lang.Value)
fmt.Println(cfg.Database.Username)
tmpl, _ = template.New("").ParseFiles(fmt.Sprint("templates/", lang.Value, "/page-", lang.Value, ".html"), "base.html")
}
tmpl.ExecuteTemplate(w, "base", nil)
}
func main() {
port := "8090"
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./public"))))
http.HandleFunc("/", index)
fmt.Println("Listening to port:", port)
error := http.ListenAndServe(":"+port, nil)
fmt.Println(error)
}
模板文件如下:
// base.html
{{define "base"}}
<!DOCTYPE html>
<html lang="en">
<link rel="shortcut icon" href="favicon.ico" />
<script>
function setLanguage(lang) {
document.cookie = "language="+lang;
location.reload();
}
</script>
<body>
<a href="#" onclick="setLanguage('en')">English</a>
<a href="#" onclick="setLanguage('ar')">عربي</a>
<br/>
{{template "content" .}}
<br/>
footer...
</body>
</html>
{{end}}
// templates/page-en.html
{{define "content"}}
Welcome
{{end}}
// templates/page-ar.html
{{define "content"}}
أهلا و سهلا
{{end}}
配置文件如下:
// configuration/en.yml
# Server configurations
server:
host: "localhost"
port: 8000
# Database credentials
database:
user: "admin"
pass: "password"
// configuration/ar.yml
# تعريف الخادم
server:
host: "localhost"
port: 8000
# كلمة الس لقاعدة البيانات
database:
user: "مدير"
pass: "كلمة سر"
go.mod 文件是:
module hasan/web
go 1.16
require gopkg.in/yaml.v2 v2.4.0
更多关于Golang中如何实现服务器响应的双重返回的实战教程也可以访问 https://www.itying.com/category-94-b0.html
3 回复
一个可能的原因是浏览器因为网站图标而请求了你的页面两次。乍一看,请求网站图标和页面本身调用了同一个处理程序。
更多关于Golang中如何实现服务器响应的双重返回的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
添加一个标签来识别打印的是哪个变量,例如:
fmt.Println("lang.Value=", lang.Value)
fmt.Println("UserName=", cfg.Database.Username)
在您的代码中,双重打印是由于浏览器对 /favicon.ico 的自动请求触发了两次 index 处理函数调用。浏览器在加载页面时会自动请求 favicon,而您的处理函数对所有路径(包括 /favicon.ico)都执行了相同的逻辑。
以下是修改后的代码,通过检查请求路径来避免重复处理:
func index(w http.ResponseWriter, r *http.Request) {
// 跳过 favicon.ico 请求
if r.URL.Path == "/favicon.ico" {
http.ServeFile(w, r, "./public/favicon.ico")
return
}
var tmpl *template.Template
var cfg Config
lang, err := r.Cookie("language")
if err != nil {
readFile(&cfg, "en")
tmpl, _ = template.New("").ParseFiles(fmt.Sprint("templates/en/page-en.html"), "base.html")
} else {
readFile(&cfg, lang.Value)
fmt.Println(lang.Value)
fmt.Println(cfg.Database.Username)
tmpl, _ = template.New("").ParseFiles(fmt.Sprint("templates/", lang.Value, "/page-", lang.Value, ".html"), "base.html")
}
tmpl.ExecuteTemplate(w, "base", nil)
}
更好的做法是使用 http.FileServer 处理静态文件,并确保 favicon 文件存在于指定路径:
func main() {
port := "8090"
// 创建文件服务器处理静态文件
fs := http.FileServer(http.Dir("./public"))
http.Handle("/static/", http.StripPrefix("/static/", fs))
http.Handle("/favicon.ico", fs)
http.HandleFunc("/", index)
fmt.Println("Listening to port:", port)
error := http.ListenAndServe(":"+port, nil)
fmt.Println(error)
}
同时确保在 ./public 目录下存在 favicon.ico 文件。

