【问题标题】:Golang Goji: How to serve static content and api at the same timeGolang Goji:如何同时提供静态内容和 api
【发布时间】:2014-12-06 20:19:02
【问题描述】:

过去两周我一直在玩 Golang,终于可以制作一个真正的应用程序了。它使用 NGINX 提供的静态 HTML 文件,API 使用 Goji Web 框架作为后端。我不使用任何 Golang 模板,因为一切都是 Angular.Js,所以静态就可以满足我的需求。

我希望可以选择是在生产环境中使用 NGINX,还是让 Go 使用应用程序使用的相同端口 (8000) 在根目录提供静态内容。这样开发环境就不需要安装 NGINX。

所以,尝试像这样向默认多路复用器添加句柄

goji.DefaultMux.Handle("/*", serveStatic)

func serveStatic(w http.ResponseWriter, r *http.Request) {
//http.ServeFile(w, r, r.URL.Path[1:])
//http.FileServer(http.Dir("static"))
http.StripPrefix("/static/", http.FileServer(http.Dir("static")))

}

此句柄在所有 API 路径都已注册后执行(否则 API 将无法工作)。

我已经尝试过任何类型的组合,要么将我重定向到 HTTP 404,要么将 HTML 内容显示为文本。两者都不好。我想知道是否有人来过这里并且可以提醒我我做错了什么。

谢谢。

虽然这与我的问题无关,但这是我正在使用的 NGINX 配置:

server {
listen 80;

# enable gzip compression
    gzip on;
    gzip_min_length  1100;
    gzip_buffers  4 32k;
    gzip_types    text/plain application/x-javascript text/xml text/css;
    gzip_vary on;
# end gzip configuration

location / {
    root /home/mleyzaola/go/src/bitbucket.org/mauleyzaola/goerp/static;
    try_files $uri $uri/ /index.html = 404;
}

location /api {
    proxy_pass http://localhost:8000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

}

【问题讨论】:

    标签: go goji


    【解决方案1】:

    我遇到过类似的问题,所以以下几点可能会有所帮助。

    • 记住将处理静态内容的处理程序注册为最终路由。否则,它可能会匹配所有内容。

    • 也许尝试使用绝对路径而不是相对路径。

    这是我使用 Goji 设置路线的简化版本。

    func apiExampleHandler(context web.C, resp http.ResponseWriter, req *http.Request) {
        fmt.Fprint(resp, "You've hit the API!")
    }
    
    func main() {
        goji.Handle("/api", apiExampleHandler)
    
        // Static file handler should generally be the last handler registered. Otherwise, it'll match every path.
        // Be sure to use an absolute path.
        staticFilesLocation := "Some absolute to the directory with your static content."
        goji.Handle("/*", http.FileServer(http.Dir(staticFilesLocation)))
    
        goji.Serve()
    }
    

    【讨论】:

    • 有趣的是我从来没有想出绝对路径。是的,它确实有效。非常感谢您花时间创建回购。现在我只需要处理作为纯文本的 HTML,猜测应该调整响应头。再次,非常感谢队友!
    • 万一有人来了,还有一个绝对文件路径的替代方案:goji.Handle("/*", http.FileServer(http.Dir("./static"))),其中“静态”目录位于 go 应用程序中。
    【解决方案2】:

    如果您可以完全控制您的网址,一个简单的策略是在顶层划分它们。我在所有应用程序 URL 的开头使用 /a,在所有静态 URL 的开头使用 /s。这使得路由非常简单。

    我使用 Goji 有一段时间,然后切换到 Gocraft-web。但原则是相同的,因为 URL 对任一框架都是明确的。 Gocraft-web 显然可以做子路由;我认为 Goji 也可以做到这一点,但不太明显。子路由之所以有用有几个原因:

    • 这是一种消除歧义的简单方法
    • 如果搜索模式更简单,路由器可能会更快
    • 您可以划分代码以便更容易理解

    如果您在生产环境中提供静态资产,您可能希望对其进行衡量并提高其性能。我发现预压缩 (gzip) 我的 JS 和 CSS 文件会有所帮助。我在同一个文件系统中有未压缩和压缩版本,并且我有一个定制的静态资产包,可以发现预压缩文件并将它们提供给所有理解的客户端(几乎是所有浏览器)。此外,设置未来的到期日也值得探索。这两个想法都内置在 Nginx 中,并且很容易编写代码。

    【讨论】:

    • 是的,子路由更清晰,但我没有那么糟糕的时间一一编写路由。关于 Gocraft-Web,我在下定决心之前评估了该框架,发现 Goji 更易于使用。此外,如果您查看这些基准测试github.com/julienschmidt/go-http-routing-benchmark,您会发现 Goji 的性能优于 Gocraft-web。关于压缩我完全同意你的观点,实际上 Nginx 是选择用于生产的 Web 服务器。这个问题是由于 Nginx 繁琐的开发环境(Windows)造成的。我通常在 Linux 上开发,所以不用担心。还是谢谢。
    • Julien Schmidt 的 HttpRouter 看起来令人印象深刻(尽管它们是他的基准,所以它们并不公正)。 (github.com/julienschmidt/httprouter)
    • 我怀疑他不是在比较同类,例如Gocraft-web 子路由反对他的自动子路由。所以基准测试让他的 API 看起来不错。不过,这意味着他喜欢简单。
    • 同意,基准测试不能太认真,但 Goji 仍然足够快满足我的需求。
    • 在他的基准测试中,我昨天试用了 HttpRouter - 我喜欢它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-13
    • 2013-09-23
    • 1970-01-01
    • 2011-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多