为了更好地理解您的问题,请问您需要将这段内容翻译成哪种语言?

huangapple go评论136阅读模式
英文:

Serving static files Go seems inefficient..or maybe its just me 为了更好地理解您的问题,请问您需要将这段内容翻译成哪种语言?

问题

在过去的几个月里,我阅读了大量关于Go语言和最佳实践的文章。其中包括了许多关于如何以及最佳方式提供静态文件的谷歌搜索和Stack Overflow搜索的结果。

以下是我目前的代码:

fs := http.FileServer(http.Dir("static/"))
myRouter.PathPrefix("/static/").Handler(http.StripPrefix("/static/", fs))

myRouter.PathPrefix("/admin/static/").Handler(http.StripPrefix("/admin/static/", fs))
myRouter.PathPrefix("/admin/accounts/static/").Handler(http.StripPrefix("/admin/accounts/static/", fs))
myRouter.PathPrefix("/admin/admin_tools/static/").Handler(http.StripPrefix("/admin/admin_tools/static/", fs))
myRouter.PathPrefix("/admin/audit_tools/static/").Handler(http.StripPrefix("/admin/audit_tools/static/", fs))
myRouter.PathPrefix("/admin/demand/static/").Handler(http.StripPrefix("/admin/demand/static/", fs))
myRouter.PathPrefix("/admin/optimization/static/").Handler(http.StripPrefix("/admin/optimization/static/", fs))
myRouter.PathPrefix("/admin/reports/static/").Handler(http.StripPrefix("/admin/reports/static/", fs))
myRouter.PathPrefix("/admin/setups/static/").Handler(http.StripPrefix("/admin/setups/static/", fs))
myRouter.PathPrefix("/admin/queue/static/").Handler(http.StripPrefix("/admin/queue/static/", fs))
myRouter.PathPrefix("/admin/tagservers/static/").Handler(http.StripPrefix("/admin/tagservers/static/", fs))
myRouter.PathPrefix("/admin/client/static/").Handler(http.StripPrefix("/admin/client/static/", fs))
myRouter.PathPrefix("/client/static/").Handler(http.StripPrefix("/client/static/", fs))

我对这段代码的问题在于,对于每个路径,我都必须添加一行新的代码来处理静态文件的来源。大多数示例只展示了在只有一个单一着陆页且没有实际导航的情况下如何处理。作为一个有Python背景的开发者,我可能有点被一些轻量级框架(如Flask和Tornado)宠坏了,因为在这些框架中,你只需要指定一次静态文件夹的位置。

另一个问题是,这种当前的设置与NGINX不兼容。再次以Flask和Tornado等框架为例,你只需要在NGINX中设置一次静态文件位置。但是在Go中,我必须像上面的代码一样设置静态文件位置(通过定义每个路径)。

**有没有人找到更好的提供静态文件的方法?**我知道理论上可以编写一个函数来自动化这个过程,但这并不改变每个路径都必须在应用程序层面和NGINX层面进行处理的事实。

**更新:**回复@mkopriva,我附上了两张截图。第一张是浏览器运行应用程序时打开开发工具显示静态文件的404错误。第二张是服务器代码,我只是注释掉了一行代码来产生这些错误。被注释掉的是处理audit_tools路径的那一行。如果我取消注释,一切都能正常路由。

为了更好地理解您的问题,请问您需要将这段内容翻译成哪种语言?
为了更好地理解您的问题,请问您需要将这段内容翻译成哪种语言?

编辑,@mkopriva和@sberry都做得很好。我希望我能选择两个正确答案。

英文:

Over months I've read tons of articles about Go and best practices. Among those articles are numerous google searches and SOF searches regarding how to and the best way to serve static files.

This is what I currently have

fs := http.FileServer(http.Dir("static/"))
myRouter.PathPrefix("/static/").Handler(http.StripPrefix("/static/", fs))

myRouter.PathPrefix("/admin/static/").Handler(http.StripPrefix("/admin/static/", fs))
myRouter.PathPrefix("/admin/accounts/static/").Handler(http.StripPrefix("/admin/accounts/static/", fs))
myRouter.PathPrefix("/admin/admin_tools/static/").Handler(http.StripPrefix("/admin/admin_tools/static/", fs))
myRouter.PathPrefix("/admin/audit_tools/static/").Handler(http.StripPrefix("/admin/audit_tools/static/", fs))
myRouter.PathPrefix("/admin/demand/static/").Handler(http.StripPrefix("/admin/demand/static/", fs))
myRouter.PathPrefix("/admin/optimization/static/").Handler(http.StripPrefix("/admin/optimization/static/", fs))
myRouter.PathPrefix("/admin/reports/static/").Handler(http.StripPrefix("/admin/reports/static/", fs))
myRouter.PathPrefix("/admin/setups/static/").Handler(http.StripPrefix("/admin/setups/static/", fs))
myRouter.PathPrefix("/admin/queue/static/").Handler(http.StripPrefix("/admin/queue/static/", fs))
myRouter.PathPrefix("/admin/tagservers/static/").Handler(http.StripPrefix("/admin/tagservers/static/", fs))
myRouter.PathPrefix("/admin/client/static/").Handler(http.StripPrefix("/admin/client/static/", fs))
myRouter.PathPrefix("/client/static/").Handler(http.StripPrefix("/client/static/", fs))

My issue with this is that for every path I have to add a new line to cover where the static files come from. Most examples show how it's done when you have a single landing page with no real navigations built into it. Coming from a Python background I suppose I was bit spoiled with some of the lightweight frameworks, such as Flask and Tornado, where one just points to the static folder once.

Another issue with this current setup is it doesn't play nice with NGINX. Again with frameworks like Flask and Tornado, all you have to do in NGINX is set the static location once. With Go I have to set the static location just like the code above (by defining each path).

Has anyone found a better way to serve static files? I know in theory a function could probably be written to automate it, but it wouldn't really change the fact that each path has to be accounted for on the app level and NGINX level.

UPDATE: In reply to @mkopriva I've attached two screenshots. The first is of the browser running the app with dev tools open to show the 404s on the static files. The Second is of the server code, to produce those errors all I did was comment out one line. The line that handles the audit_tools path. If I uncomment it everything routes no problem.

为了更好地理解您的问题,请问您需要将这段内容翻译成哪种语言?
为了更好地理解您的问题,请问您需要将这段内容翻译成哪种语言?

Edit, both @mkopriva and @sberry did a great job. I wish I could pick two correct answers.

答案1

得分: 2

如果你正在使用nginx来完成这个工作,那么你不需要使用Go(除非你想要能够独立运行而不依赖nginx)。如果是这种情况,你可以使用Path调用而不是PathPrefix,这样你就可以进行模式匹配。

如果你只是想通过nginx来完成这个任务,那么下面的配置应该可以工作:

server {
    listen 8080;
   
    location ~* ^/static/ {
        root /path/to/directory/containing_static;
    }

    location  ~* ^.*/static/(.*)$ {
        rewrite "^.*/static/(.*)$" /static/$1 last;
    }


    location @forward_to_app {
       # 在这里发送到你的Go应用程序
    }

}

你可能可以不使用rewrite,但这是一种简单的方法。

英文:

If you are using nginx to do this work then you don't need Go to do it too (unless you want to be able to run standalone without nginx). If that is the case then you can use a Path call instead of PathPrefix so you can do pattern matching.

If you are just trying to do this via nginx then something like this should work:

server {
    listen 8080;
   
    location ~* ^/static/ {
        root /path/to/directory/containing_static;
    }

    location  ~* ^.*/static/(.*)$ {
        rewrite "^.*/static/(.*)$" /static/$1 last;
    }


    location @forward_to_app {
       # send to your go app here
    }

  }

You can probably do without the rewrite, but that was an easy approach to take.

答案2

得分: 2

所有这些PathPrefixStripPrefix调用对我来说似乎没有实际意义。如果你的静态目录位于Go项目内部,并且其结构类似于这样:

.
├── main.go
└── static
    ├── admin
    │   ├── accounts
    │   │   └── file.txt
    │   ├── file.txt
    │   └── reports
    │       └── file.txt
    └── file.txt

那么要使用Go来提供该静态目录中的文件,你实际上只需要这样做。

package main

import (
    "log"
    "net/http"
)

func main() {
    fs := http.FileServer(http.Dir("static/"))
    http.Handle("/", fs)

    log.Fatal(http.ListenAndServe(":8080", nil))
}

为了更好地理解您的问题,请问您需要将这段内容翻译成哪种语言?

英文:

All those PathPrefix and StripPrefix calls seem to me to be functionally pointless. If your static directory is inside your Go project and its structure looks something like this:

.
├── main.go
└── static
    ├── admin
    │   ├── accounts
    │   │   └── file.txt
    │   ├── file.txt
    │   └── reports
    │       └── file.txt
    └── file.txt

then to serve files from that static directory with Go, all you should really need is this.

package main

import (
	"log"
	"net/http"
)

func main() {
	fs := http.FileServer(http.Dir("static/"))
	http.Handle("/", fs)

	log.Fatal(http.ListenAndServe(":8080", nil))
}

为了更好地理解您的问题,请问您需要将这段内容翻译成哪种语言?

huangapple
  • 本文由 发表于 2017年3月31日 11:37:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/43132005.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定