ch4/ch4-06 #192
Replies: 4 comments 2 replies
-
4.14
|
Beta Was this translation helpful? Give feedback.
-
这可比 jS麻烦的不是一点半点啊 |
Beta Was this translation helpful? Give feedback.
-
package github import ( // GitHub 搜索 Issues 的 URL // 定义用户信息 // 定义 Issue 信息 // GitHub 搜索结果结构体 // 模板字符串 GitHub Issues 搜索{{if .Result}}共找到 {{.Result.TotalCount}} 个 Issues{{range .Result.Items}} {{end}}
// PageData 用于传递给模板的数据 // WebServer 启动 HTTP 服务器 // Handle 处理 HTTP 请求
} |
Beta Was this translation helpful? Give feedback.
-
4.14package main
import (
"encoding/json"
"fmt"
"html/template"
"net/http"
"net/url"
"os"
"strings"
)
// GitHub 搜索 Issues 的 API 地址
const baseURL = "https://api.github.com/search/issues"
// 用户结构体
type User struct {
Login string `json:"login"`
HTMLURL string `json:"html_url"`
}
// issue 结构体
type Issue struct {
Number int `json:"number"`
HTMLURL string `json:"html_url"`
Title string `json:"title"`
State string `json:"state"`
User *User `json:"user"`
}
// 搜索结果结构体
type IssuesSearchResult struct {
TotalCount int `json:"total_count"`
Items []*Issue `json:"items"`
}
// 页面数据结构体(用于模板渲染)
type PageData struct {
SearchKey string
Result *IssuesSearchResult
Error string
}
// HTML 模板
var tmpl = `
<!DOCTYPE html>
<html>
<head>
<title>GitHub Issues 搜索</title>
<style>
body { font-family: Arial, sans-serif; padding: 20px; }
table { border-collapse: collapse; width: 100%; margin-top: 20px; }
th, td { border: 1px solid #ddd; padding: 8px; }
th { background-color: #f2f2f2; }
</style>
</head>
<body>
<h1>GitHub Issues 搜索</h1>
<form method="GET">
<input type="text" name="key" placeholder="例如 repo:golang/go is:open" value="{{.SearchKey}}" style="width: 300px;" />
<button type="submit">搜索</button>
</form>
{{if .Error}}
<p style="color: red;">{{.Error}}</p>
{{end}}
{{if .Result}}
<h2>共找到 {{.Result.TotalCount}} 个 Issues</h2>
<table>
<tr>
<th>#</th>
<th>状态</th>
<th>用户</th>
<th>标题</th>
</tr>
{{range .Result.Items}}
<tr>
<td><a href="{{.HTMLURL}}" target="_blank">#{{.Number}}</a></td>
<td>{{.State}}</td>
<td><a href="{{.User.HTMLURL}}" target="_blank">{{.User.Login}}</a></td>
<td>{{.Title}}</td>
</tr>
{{end}}
</table>
{{end}}
</body>
</html>
`
// 启动 Web 服务
func main() {
http.HandleFunc("/", handle)
fmt.Println("🚀 服务器已启动:http://127.0.0.1:5000/")
http.ListenAndServe("127.0.0.1:5000", nil)
}
// 请求处理函数
func handle(w http.ResponseWriter, r *http.Request) {
// 解析模板
t := template.Must(template.New("webpage").Parse(tmpl))
// 获取参数
key := strings.TrimSpace(r.URL.Query().Get("key"))
data := PageData{SearchKey: key}
if key == "" {
// 初始页只渲染搜索框
t.Execute(w, data)
return
}
// 构造 GitHub API URL(加上 URL 编码)
query := url.QueryEscape(key)
apiURL := baseURL + "?q=" + query
// 构造请求并添加必要头
req, err := http.NewRequest("GET", apiURL, nil)
if err != nil {
data.Error = "创建请求失败: " + err.Error()
t.Execute(w, data)
return
}
req.Header.Set("User-Agent", "Go-GitHub-Issue-Searcher")
if token := os.Getenv("GITHUB_TOKEN"); token != "" {
req.Header.Set("Authorization", "token "+token)
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
data.Error = "请求失败: " + err.Error()
t.Execute(w, data)
return
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
data.Error = fmt.Sprintf("GitHub API 错误:%d", resp.StatusCode)
t.Execute(w, data)
return
}
// 解析响应
var result IssuesSearchResult
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
data.Error = "解析响应失败: " + err.Error()
t.Execute(w, data)
return
}
data.Result = &result
t.Execute(w, data)
} |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
ch4/ch4-06
中文版
https://golang-china.github.io/gopl-zh/ch4/ch4-06.html
Beta Was this translation helpful? Give feedback.
All reactions