用go来搭建一个简单的图片上传网站
程序员文章站
2022-04-08 16:49:05
...
提前说明一下:代码参考了《Go语言编程》,稍有变动, 自己亲自玩了一遍。
之前玩过go web server, 现在来用go来搭建一个简单的图片上传网站, 工作目录是:~/photoweb , 而~/photoweb/uploads用来存图片,代码photoweb.go在~/photoweb目录下。
看服务器代码, ~/photoweb/photoweb.go的内容为:
package main
import (
"io"
"os"
"log"
"net/http"
)
const (
UPLOAD_DIR = "./uploads"
)
func uploadHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" {
str := `
<html>
<head>
<meta charset="utf-8">
<title>Upload</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>`
io.WriteString(w, str)
}
// 处理图片上传
if r.Method == "POST" {
f, h, err := r.FormFile("image")
if err != nil {
http.Error(w, err.Error(),
http.StatusInternalServerError)
return
}
filename := h.Filename
defer f.Close()
t, err := os.Create(UPLOAD_DIR + "/" + filename)
if err != nil {
http.Error(w, err.Error(),
http.StatusInternalServerError)
return
}
defer t.Close()
if _, err := io.Copy(t, f); err != nil {
http.Error(w, err.Error(),
http.StatusInternalServerError)
return
}
}
}
func main() {
http.HandleFunc("/upload", uploadHandler)
err := http.ListenAndServe(":8080", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err.Error())
}
}
在浏览器中执行:http://127.0.0.1:8080/upload
后台代码进入GET分支, 给浏览器端返回一段html代码,展示成html元素, 供用户上传图片, 选择图片, 点击Upload按钮上传后, 后台代码进入POST分支, 于是把图片存到了~/photoweb/uploads中。实际check了一下, 该目录下果然有此图片。
为了便于在浏览器上直接查看上传的图片, 可以修改下服务器代码, 增加Redirect, 如下:
package main
import (
"io"
"os"
"log"
"net/http"
)
const (
UPLOAD_DIR = "./uploads"
)
func uploadHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" {
str := `
<html>
<head>
<meta charset="utf-8">
<title>Upload</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>`
io.WriteString(w, str)
}
// 处理图片上传
if r.Method == "POST" {
f, h, err := r.FormFile("image")
if err != nil {
http.Error(w, err.Error(),
http.StatusInternalServerError)
return
}
filename := h.Filename
defer f.Close()
t, err := os.Create(UPLOAD_DIR + "/" + filename)
if err != nil {
http.Error(w, err.Error(),
http.StatusInternalServerError)
return
}
defer t.Close()
if _, err := io.Copy(t, f); err != nil {
http.Error(w, err.Error(),
http.StatusInternalServerError)
return
}
http.Redirect(w, r, "/view?id="+filename, http.StatusFound)
}
}
func isExists(path string) bool {
_, err := os.Stat(path)
if err == nil {
return true
}
return os.IsExist(err)
}
func viewHandler(w http.ResponseWriter, r *http.Request) {
imageId := r.FormValue("id")
imagePath := UPLOAD_DIR + "/" + imageId
if exists := isExists(imagePath); !exists {
http.NotFound(w, r)
return
}
w.Header().Set("Content-Type", "image")
http.ServeFile(w, r, imagePath)
}
func main() {
http.HandleFunc("/view", viewHandler)
http.HandleFunc("/upload", uploadHandler)
err := http.ListenAndServe(":8080", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err.Error())
}
}
重启服务,重新访问http://127.0.0.1:8080/upload, 然后选择图片, 点击Upload上传, 结果在服务器对应的目录中有该图片, 且在浏览器中显示了该图片。
如上代码很简单, 我之前在Apatch下写过类似的图片上传服务器, 道理基本相同。
好了, 不多说。
上一篇: 一个图片上传的时预览页面超级简单
推荐阅读