有過(guò) Python Web 開(kāi)發(fā)經(jīng)驗(yàn)的朋友,相信對(duì)它的便利性肯定印象非常深刻。其實(shí)利用 Go 語(yǔ)言對(duì) Web 網(wǎng)站進(jìn)行開(kāi)發(fā)也是非常容易的一件事情。之前我對(duì) Web 開(kāi)發(fā)的經(jīng)驗(yàn)也為 0,但是使用 Go 語(yǔ)言之后,你可以在最短的時(shí)間內(nèi)搭建一個(gè)網(wǎng)站。
為了學(xué)習(xí)的方便,大家可以直接從 Github 上下載到本篇博客談到的所有代碼。同時(shí),文章中的代碼部分引用了《Go語(yǔ)言編程》中的代碼內(nèi)容,在此一并表示感謝。本次內(nèi)容的地址在這,有興趣的同學(xué)可以下載看一下。
從目錄上看,代碼的內(nèi)容非常簡(jiǎn)單。picture.go 包含了所有的交互代碼,list.html 和 upload.html 則包含了使用到的模板文件,而 uploads 目錄則保存了所有上傳的 image 文件。
首先看看 picture.go 代碼內(nèi)容,
package main
import "io"
import "log"
import "os"
import "net/http"
import "html/template"
import "io/ioutil"
const (
UPLOAD_DIR = "./uploads"
)
func uploadHandler (w http.ResponseWriter, r * http.Request) {
if r.Method == "GET" {
t, _ := template.ParseFiles("upload.html")
t.Execute(w, nil)
}else {
f, h, _ := r.FormFile("image")
filename := h.Filename
defer f.Close()
t, _ := os.Create(UPLOAD_DIR + "/" + filename)
defer t.Close()
_, err := io.Copy(t, f)
if err != nil {
return
}
http.Redirect(w, r, "view?id=" + filename, http.StatusFound)
}
}
func viewHandler(w http.ResponseWriter, r* http.Request) {
imageId := r.FormValue("id")
imagePath := UPLOAD_DIR + "/" + imageId
w.Header().Set("Content-Type", "image")
http.ServeFile(w, r, imagePath)
}
func listHandler(w http.ResponseWriter, r* http.Request) {
fileInfoArr, _ := ioutil.ReadDir(UPLOAD_DIR)
locals := make(map[string] interface{})
images := []string{}
for _, fileInfo := range fileInfoArr {
images = append(images, fileInfo.Name())
}
locals["images"] = images
t, _ := template.ParseFiles("list.html")
t.Execute(w, locals)
}
func main() {
http.HandleFunc("/upload", uploadHandler)
http.HandleFunc("/view", viewHandler)
http.HandleFunc("/", listHandler)
err := http.ListenAndServe(":9090", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err.Error())
}
}
其實(shí)這個(gè)網(wǎng)站主要就 3 個(gè)網(wǎng)頁(yè)。一個(gè)是顯示所有圖片的索引,一個(gè)是圖片顯示,另外一個(gè)就是圖片上傳頁(yè)面。
下面看看,upload.html 內(nèi)容有哪些?
<!doctype html>
<html>
<head>
<meta charset = "utf-8">
<tilte> Uploader </title>
</head>
<body>
<form method="post" action="/upload" enctype="multipart/form-data">
Choose an image to upload: <input name="image" type="file" />
<input type="submit" value="Upload" />
</form>
</body>
</html>
有過(guò)前端開(kāi)發(fā)經(jīng)驗(yàn)的朋友肯定一眼就看出來(lái)了,這其實(shí)就是個(gè)簡(jiǎn)單的登錄上傳頁(yè)面。那么 list.html 又是什么東西呢?
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title> List </title>
</head>
<body>
<ol>
{{range $.images}}
<li><a href="/view?id={{.|urlquery}}"> {{.|html}} </a> </li>
{{end}}
</ol>
</body>
</html>
上面的網(wǎng)頁(yè)與其說(shuō)是一個(gè)網(wǎng)頁(yè),倒不如說(shuō)是一個(gè)模板。因?yàn)樗械?images 內(nèi)容其實(shí)都要從外界進(jìn)行傳遞的,而這所有的內(nèi)容才會(huì)構(gòu)成一個(gè)真正的網(wǎng)頁(yè)。