提供静态文件Go似乎效率低下......或许它只是我:-)

时间:2017-03-31 03:37:54

标签: go

几个月来,我读过很多关于Go和最佳实践的文章。在这些文章中有许多关于如何以及提供静态文件的最佳方式的谷歌搜索和SOF搜索。

这就是我目前所拥有的

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路径的行。如果我取消注释,一切都没有问题。

Browser Errors Server code with commented out line

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

2 个答案:

答案 0 :(得分: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 {
       # send to your go app here
    }

  }

你可能没有重写,但这是一个简单的方法。

答案 1 :(得分: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))
}

enter image description here