這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
建網站不可避免的要使用各種各樣的靜態資源,這一節,就來看看,如何載入css,js圖片等等這些資源。
在之前的基礎上構造一簡單的個HTML的測試檔案
<HTML> <head> <title>Hello World</title> <link href="static/core.css" type="text/css" rel="stylesheet" /> </head> <body> <div id="header"> <p>this is header</p> </div> <div id="main"> <p> this is main<br /> {{.Name | showname}} </p> </div> <div id="footer"> <p>this is footer</p> </div> </body> </HTML>
再建立一個css檔案:
* { font-size: 30px; font-weight: bold; }#header { background-color: red }#main { background-color: yellow; }#footer { background-color: blue; }
然後運行之前的go檔案,結果如下:
從運行結果來看,會發現css並沒有起作用,我們來看一看為什麼會這樣:
先做一個簡單的測試:
我們之前在main方法中註冊了一個路由:
http.HandleFunc("/", Index)
我們期望的是當直接存取 http://localhost:8080 時就能轉到index.html
頁面。
但事實上呢?
我們來試一試這個地址:
http://localhost:8080/core.css
同樣的得到的是index.html這個頁面的內容,
也就是說我們註冊的路由也匹配到了/core.css這個請求
問題出在哪裡呢?
我們得自己寫一個路由函數,來看看是如何匹配路由的:
先看一下go的文檔:看看ListenAndServe函數的聲明:
func ListenAndServe(addr string, handler Handler) error
如果要自己寫路由函數的話,就得先實現Handler這個介面,聲明如下:
type Handler interface { ServeHTTP(ResponseWriter, *Request) }
先聲明一個結構體:
type MyMux struct { routers map[string]func(http.ResponseWriter,*http.Request) }
實現ServeHTTP方法:
func (p *MyMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { //遍曆routers,尋找匹配的path for path, f := range p.routers { if r.URL.Path == path { f(w, r) return } } fmt.Fprintf(w, "Error: Don't match URL '%s'", r.URL.Path)}
重寫main函數:
func main() { mux := &MyMux{} mux.routers = make(map[string]func(http.ResponseWriter, *http.Request)) mux.routers["/"] = Index err := http.ListenAndServe(":8080", mux) if err != nil { fmt.Println("Error: ", err) }}
這樣的話對於每一次的請求,都遍曆一次mux.routers,來尋找是否有匹配到的路由,
但很顯然,如果使用 “r.URL.Path == path” 這樣的方式,是沒法滿足要求的,
因為你得列出每一種可能出現的path,這明顯是不現實的,我們接下來考慮使用Regex來匹配路由規則。
我們需要重新實現ServeHTTP方法,但也只需要修改if的判斷條件即可:
但不要忘了匯入regexpRegex包
if ok, _ :=regexp.MatchString("^" + path + "$", r.URL.Path); ok { f(w, r) return }
並且新增一條是用Regex的路由:
mux.routers["/static/.+"] = Static
接下來,我們就要針對匹配到的static檔案中的檔案做單獨的處理
func Static(w http.ResponseWriter, r *http.Request) { fmt.Println("Deal Static: ", r.URL.Path) w.Header().Set("Content-Type", "text/css") http.ServeFile(w, r, "." + r.URL.Path)}
現在再通過瀏覽器分別訪問一下URL:
http://localhost:8080/
http://localhost:8080/static/core.css
發現已經匹配正常了。
雖然醜了點,但不要在意那麼多細節啦,只是用來示範一下。
當我們訪問 http://localhost:8080/ 的時候,瀏覽器會向伺服器發送一個GET /static/core.css
的請求,伺服器會匹配到 /static/.+ 這條規則,然後調用func Static()函數,那麼在該函數中的
r.URL.Path則是/static/core.css,如果/static目錄下還有多個檔案夾的話,還要對r.URL.Path的值
另作處理,這裡就不在展開說明了。
此時,當我們訪問 http://localhost:8080/ 的時候,就會發現頁面解析正常了,效果如下:
同理,js和圖片以及其他靜態資源都可以按照上面的方法處理。