Gorilla Golang Pathprefix 不提供文件

files我的 Golang 项目目录根目录中的文件夹中有一个名为test.jpg. 那就是./files/test.jpg 我想服务于我的前端,但我遇到了困难。


我的 golang 项目在一个附有以下卷的 docker 文件中。(基本上就是说在docker容器里可以在服务器上/go/.../webserver读写出来)./


volumes:

  - ./:/go/src/github.com/patientplatypus/webserver/

我正在使用gorilla/mux由以下定义的路由:


r := mux.NewRouter()

以下是我尝试使 PathPrefix 正确格式化的一些尝试:


r.PathPrefix("/files/").Handler(http.StripPrefix("/files/", 

http.FileServer(http.Dir("/go/src/github.com/patientplatypus/webserver/files/"))))

或者


r.PathPrefix("/files").Handler(http.FileServer(http.Dir("./files/")))

或者


r.PathPrefix("/files/").Handler(http.StripPrefix("/files/",  

http.FileServer(http.Dir("./"))))

或者


r.PathPrefix("/files/").Handler(http.FileServer(

http.Dir("/go/src/github.com/patientplatypus/webserver/")))

我之前使用以下命令成功写入服务器:


newPath := filepath.Join("/go/src/github.com/patientplatypus/webserver/files", 

"test.jpg")

newFile, err := os.Create(newPath)

所以我的直觉是,我的第一次尝试应该是正确的,指定了整个路径/go/.../files/。


在任何情况下,我的每次尝试都成功地将一个空的 response.data200OK返回到我的前端,如下所示:


Object { data: "", status: 200, statusText: "OK",

headers: {…}, config: {…}, request: XMLHttpRequest }

它来自使用axios包的简单 js 前端 http 请求:


        axios({

            method: 'get',

            url: 'http://localhost:8000/files/test.jpg',

        })

        .then(response => {

            //handle success

            console.log("inside return for test.jpg and value 

            of response: ")

            console.log(response);

            console.log("value of response.data: ")

            console.log(response.data)

            this.image = response.data;

        })

        .catch(function (error) {

            //handle error

            console.log(error);

        });

关于为什么会发生这种情况,我唯一的猜测是它没有看到该文件,因此什么也不返回。


对于这样一个看似微不足道的问题,我正处于猜测和检查阶段,不知道如何进一步调试。如果有人有任何想法,请告诉我。


哔哔one
浏览 172回答 4
4回答

喵喵时光机

你能从中去掉 JavaScript 客户端,并发出一个简单的curl请求吗?用简单的文本文件替换图像以消除任何可能的内容类型/MIME 检测问题。(稍微)调整文档中发布的示例gorilla/mux:https://github.com/gorilla/mux#static-files代码func main() {&nbsp; &nbsp; var dir string&nbsp; &nbsp; flag.StringVar(&dir, "dir", ".", "the directory to serve files from. Defaults to the current dir")&nbsp; &nbsp; flag.Parse()&nbsp; &nbsp; r := mux.NewRouter()&nbsp; &nbsp; r.PathPrefix("/files/").Handler(&nbsp; &nbsp; &nbsp; &nbsp; http.StripPrefix("/files/",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; http.FileServer(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; http.Dir(dir),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ),&nbsp; &nbsp; &nbsp; &nbsp; ),&nbsp; &nbsp; )&nbsp; &nbsp; addr := "127.0.0.1:8000"&nbsp; &nbsp; srv := &http.Server{&nbsp; &nbsp; &nbsp; &nbsp; Handler:&nbsp; &nbsp; &nbsp; r,&nbsp; &nbsp; &nbsp; &nbsp; Addr:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;addr,&nbsp; &nbsp; &nbsp; &nbsp; WriteTimeout: 15 * time.Second,&nbsp; &nbsp; &nbsp; &nbsp; ReadTimeout:&nbsp; 15 * time.Second,&nbsp; &nbsp; }&nbsp; &nbsp; log.Printf("listening on %s", addr)&nbsp; &nbsp; log.Fatal(srv.ListenAndServe())}运行服务器➜&nbsp; /mnt/c/Users/matt/Dropbox&nbsp; go run static.go -dir="/home/matt/go/src/github.com/gorilla/mux"2018/09/05 12:31:28 listening on 127.0.0.1:8000获取文件➜&nbsp; ~&nbsp; curl -sv localhost:8000/files/mux.go | head*&nbsp; &nbsp;Trying 127.0.0.1...* Connected to localhost (127.0.0.1) port 8000 (#0)> GET /files/mux.go HTTP/1.1> Host: localhost:8000> User-Agent: curl/7.47.0> Accept: */*>< HTTP/1.1 200 OK< Accept-Ranges: bytes< Content-Length: 17473< Content-Type: text/plain; charset=utf-8< Last-Modified: Mon, 03 Sep 2018 14:33:19 GMT< Date: Wed, 05 Sep 2018 19:34:13 GMT<{ [16384 bytes data]* Connection #0 to host localhost left intact// Copyright 2012 The Gorilla Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package muximport (&nbsp; &nbsp; &nbsp; &nbsp; "errors"&nbsp; &nbsp; &nbsp; &nbsp; "fmt"&nbsp; &nbsp; &nbsp; &nbsp; "net/http"请注意,实现此目的的“正确”方法是按照您的第一个示例:r.PathPrefix("/files/").Handler(http.StripPrefix("/files/",&nbsp;http.FileServer(http.Dir("/go/src/github.com/patientplatypus/webserver/files/"))))从路径中删除/files/前缀,这样文件服务器就不会尝试查找/files/go/src/...。确保这/go/src/...是正确的——您提供的是从文件系统根目录开始的绝对路径,而不是从您的主目录开始的(这是您的意图吗?)如果这是您的意图,请确保/go/src/...运行您的应用程序的用户可以读取它。

大话西游666

所以,这不是一个很好的解决方案,但它(目前)有效。我看到了这个帖子:Golang。用什么?http.ServeFile(..) 还是 http.FileServer(..)?,显然您可以使用较低级别的 apiservefile而不是添加了保护的文件服务器。所以我可以使用r.HandleFunc("/files/{filename}", util.ServeFiles)和func ServeFiles(w http.ResponseWriter, req *http.Request){&nbsp; &nbsp; fmt.Println("inside ServeFiles")&nbsp; &nbsp; vars := mux.Vars(req)&nbsp; &nbsp; fileloc := "/go/src/github.com/patientplatypus/webserver/files"+"/"+vars["filename"]&nbsp; &nbsp; http.ServeFile(w, req, fileloc)}再次不是一个很好的解决方案,我并不兴奋 - 我将不得不在获取请求参数中传递一些身份验证内容以防止 1337h4x0rZ。如果有人知道如何启动和运行 pathprefix,请告诉我,我可以重构。感谢所有帮助过的人!

GCT1015

我通常只是将文件资产捆绑到我编译的应用程序中。然后应用程序将以相同的方式运行和检索资产,无论您是在容器中运行还是在本地运行。我过去使用过 go-bindata,但看起来这个包似乎不再维护,但有很多替代品可用。

慕哥6287543

我和你在同一页上,完全一样,我一直在调查这件事,让它工作一整天。我卷曲了,它也像你在上面的评论中提到的那样给了我 200 个 0 字节。我在责怪码头工人。它终于奏效了,唯一的 (...) 变化是我删除了http.Dir()例如:在你的例子中,做这个:http.FileServer(http.Dir("/go/src/github.com/patientplatypus/webserver/files")))),不要添加最后一个斜杠来制作它.../files/它奏效了。它显示了图片,以及卷曲结果:HTTP/2 200&nbsp;&nbsp;accept-ranges: bytes&nbsp;content-type: image/png&nbsp;last-modified: Tue, 15 Oct 2019 22:27:48 GMT&nbsp;content-length: 107095
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go