为啥我需要使用 http.StripPrefix 来访问我的静态文件?

Posted

技术标签:

【中文标题】为啥我需要使用 http.StripPrefix 来访问我的静态文件?【英文标题】:Why do I need to use http.StripPrefix to access my static files?为什么我需要使用 http.StripPrefix 来访问我的静态文件? 【发布时间】:2015-03-12 18:38:09 【问题描述】:

main.go

package main

import (
    "net/http"
)

func main() 
    http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
    http.ListenAndServe(":8080", nil)

目录结构:

%GOPATH%/src/project_name/main.go
%GOPATH%/src/project_name/static/..files and folders ..

即使在阅读了文档之后,我也很难理解 http.StripPrefix 在这里的作用。

1) 如果我删除了http.StripPrefix,为什么我无法访问localhost:8080/static

2) 如果我删除该功能,哪个 URL 映射到 /static 文件夹?

【问题讨论】:

你试过http.Handle("/static/", http.FileServer(http.Dir("/")))吗? http.Handle("/static/", http.FileServer(http.Dir(""))) 工作。 【参考方案1】:

http.StripPrefix() 将请求的处理转发给您指定为其参数的请求,但在此之前它会通过剥离指定的前缀来修改请求 URL。

例如,如果浏览器(或 HTTP 客户端)请求资源:

/static/example.txt

StripPrefix 将剪切/static/ 并将修改后的请求转发给http.FileServer() 返回的处理程序,这样它就会看到请求的资源是

/example.txt

http.FileServer() 返回的Handler 将查找并提供文件的内容相对到指定为其参数的文件夹(或者更确切地说是FileSystem)(您指定了"static"成为静态文件的根目录)。

现在由于"example.txt" 位于static 文件夹中,您必须指定相对路径才能获得正确的文件路径。

另一个例子

此示例可以在 http 包文档页面 (here) 上找到:

// To serve a directory on disk (/tmp) under an alternate URL
// path (/tmpfiles/), use StripPrefix to modify the request
// URL's path before the FileServer sees it:
http.Handle("/tmpfiles/",
        http.StripPrefix("/tmpfiles/", http.FileServer(http.Dir("/tmp"))))

说明:

FileServer() 被告知静态文件的根是"/tmp"。我们希望 URL 以 "/tmpfiles/" 开头。所以如果有人请求"/tempfiles/example.txt",我们希望服务器发送文件"/tmp/example.txt"

为了实现这一点,我们必须从 URL 中删除 "/tmpfiles",剩下的将是与根文件夹 "/tmp" 相比的相对路径,如果我们加入的话:

/tmp/example.txt

【讨论】:

对于阅读本文的任何人,请确保您在 /tmpfiles/ 中有斜杠,否则您将度过一段糟糕的时光。 为了澄清和传播正确的常识,Handle中的/tmpfile/很重要,但在StripPrefix中不重要,假设http.Handle("/tmpfiles/", http.StripPrefix("/tmpfiles", http.FileServer(http.Dir("/tmp"))))也可以使用【参考方案2】:

我会一一回答这两个问题。

问题 1 的答案 1: 如果你的代码是这样写的:

http.Handle("/static/", http.FileServer(http.Dir("static"))

您的根文件夹是%GOPATH%/src/project_name/static/。当您访问localhost:8080/static 时,URL /static 将被转发到http.FileServer() 返回的处理程序。但是,您在根文件夹中没有名为 static 的目录或文件。

对问题 2 的回答 2:一般情况下,如果删除 http.StripPrefix(),则无法访问 /static 文件夹。但是,如果您有一个名为 static 的目录或文件,您可以使用 URL localhost:8080:/static 访问它(完全不是您想要的根目录)。

顺便说一句,如果您的 URL 不以 /static 开头,您将无法访问任何内容,因为 http.ServeMux 不会重定向您的请求。

【讨论】:

【参考方案3】:

假设

我有一个文件

/home/go/src/js/kor.js

然后,告诉 fileserve 服务于本地目录

fs := http.FileServer(http.Dir("/home/go/src/js"))

示例 1 - 指向 Filerserver 根目录的根 url

现在文件服务器将"/"请求作为"/home/go/src/js"+"/"

http.Handle("/", fs)

是的,http://localhost/kor.js 请求告诉 Fileserver,在

中找到 kor.js
"/home/go/src/js" +  "/"  + "kor.js".

我们得到了kor.js 文件。

Example2 - 文件服务器根目录的自定义 url

但是,如果我们添加额外的请求名称。

http.Handle("/static/", fs)

现在文件服务器将"/static/"请求作为"/home/go/src/js"+"/static/"

是的,http://localhost/static/kor.js 请求告诉 Fileserver,在

中找到 kor.js
"/home/go/src/js" +  "/static/"  + "kor.js".

我们收到 404 错误。

示例 3 - 自定义 url 到 Fileserver 根目录

所以,我们在 Fileserver 使用 http.StripPrefix("/tmpfiles/", ... 之前修改请求 url

stripPrefix Fileserver 之后使用/ 而不是/static/

"/home/go/src/js" +  "/"  + "kor.js".

得到kor.js

【讨论】:

【参考方案4】:

对于遇到子目录问题的任何人,您需要添加一个".",因为它似乎仅当它是二进制文件根目录中的文件夹时才将路径视为相对路径。

例如

s.router.PathPrefix("/logos/").Handler(
        http.StripPrefix("/logos/", http.FileServer(http.Dir("./uploads/logos/"))))

注意“/uploads”之前的"."

【讨论】:

以上是关于为啥我需要使用 http.StripPrefix 来访问我的静态文件?的主要内容,如果未能解决你的问题,请参考以下文章

goweb-处理静态资源

goweb之书城基本CRUD增删改查

go template修改定界符Delims的坑

go template修改定界符Delims的坑

为啥我需要使用 daphne 进行反向代理?

如果我使用类似 NHibernate 的 ORM,为啥需要 LINQ?