英文:
http.HandleFunc with Static Files
问题
我正在构建一个网页。该页面应该能够处理不同的http
方法(GET
,POST
...)。我的页面在技术上可以处理每种类型的请求,但在GET
请求的情况下(在根路径"/"
处提供index.html
),我的页面显示不正确。没有任何图像或CSS正确显示,可能是因为找不到这些文件。
我注意到,当我将http.Handle
替换到我的server.go
代码中时,与http.HandleFunc
相比,它提供了更好的结果,图像和CSS可以正确显示:
http.FileServer(http.Dir("static"))
http.Handle("/", http.StripPrefix("/", fs))
以下是我的Web服务器,其中图像和CSS显示不正确。总的来说,我的意图是为了使用静态文件来处理所有内容,包括HTML(例如index.html
),并且只使用标准的Go来实现一些解决方案。
server.go 代码
package main
import (
"net/http"
"fmt"
)
func indexHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Content Type", "text/html")
switch r.Method {
case "GET":
http.ServeFile(w, r, "./static/index.html")
case "POST":
fmt.Pprintf(w, "POST!")
case "PUT":
fmt.Pprintf(w, "PUT!")
case "DELETE":
fmt.Pprintf(w, "DELETE!")
default:
fmt.Pprintf(w, "Default!")
}
}
func main() {
http.HandleFunc("/", indexHandler)
http.ListenAndServe(":3000", nil)
}
英文:
I am building a webpage. The page should be able to handle the different http
methods (GET
, POST
...). My page technically works and handles each type of request, but in the case of GET
requests (serving index.html
at the root "/"
path), my page is not displaying properly. None of the images or css are displaying correctly, presumably because those files cannot be found.
I have noticed that http.Handle
provides better results than http.HandleFunc
when substituted into my server.go
code below, in that the images and css do display correctly using:
http.FileServer(http.Dir("static"))
http.Handle("/", http.StripPrefix("/", fs))
The following is my web server with images and css not being displayed correctly. In general, my intent is to use static files for everything, including html (ex. index.html
) and to implement some solution using nothing but standard go.
server.go code
package main
import (
"net/http"
"fmt"
)
func indexHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Content Type", "text/html")
switch r.Method {
case "GET":
http.ServeFile(w, r, "./static/index.html")
case "POST":
fmt.Pprintf(w, "POST!")
case "PUT":
fmt.Pprintf(w, "PUT!")
case "DELETE":
fmt.Pprintf(w, "DELETE!")
default:
fmt.Pprintf(w, "Default!")
}
}
func main() {
http.HandleFunc("/", indexHandler)
http.ListenAndServe(":3000", nil)
}
答案1
得分: 2
你已经在服务器中硬编码了一个规则,无论请求什么内容,它都会始终返回index.html
。所以,如果你的index.html
中包含对style.css
的引用,浏览器会发起第二个请求来获取style.css
,然后你又会返回index.html
。
我猜你想要的是让所有的GET
请求返回静态文件,而其他的请求则执行其他操作。你只需要将这些请求传递给文件服务器即可:
root := "static"
...
switch r.Method {
case "GET":
if r.URL.Path == "" || r.URL.Path == "/" {
http.ServeFile(w, r, path.Join(root, "index.html"))
} else {
http.ServeFile(w, r, path.Join(root, r.URL.Path))
}
请注意,在处理程序被调用时,URL中的所有".."引用已被移除,攻击者无法利用此来逃离静态文件目录。但是,ServeFile()
会返回目录列表,所以如果这是个问题,你需要进行检查。
英文:
You've hard-coded your server to always return index.html
for any GET request, no matter what is being requested. So if your index.html
includes a reference to style.css
, the browser is going to make a second request for style.css
and you'll return index.html
again.
I assume what you're trying to do is have all GET
requests return static files, while other verbs will do something else. You just need to pass those along to the file server:
root := "static"
...
case "GET":
if r.URL.Path == "" || r.URL.Path == "/" {
http.ServeFile(w, r, path.Join(root, "index.html"))
} else {
http.ServeFile(w, r, path.Join(root, r.URL.Path))
}
Note that by the time your handler is called, all ".." references in the URL have been removed, attackers can't use this to escape your static tree. But ServeFile()
will return directory listings, so you'll need to check for that if that's a problem.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论