我已经设置了nixOS来运行nginx作为 docker 集装箱的反向代理.在停靠容器中运行golang服务器,该服务器用函数处理/并且还从两个文件夹staticjs返回文件.它在端口8181上运行.其代码如下所示:

func main() {
        static := http.FileServer(http.Dir("static"))
        js := http.FileServer(http.Dir("js"))
        http.Handle("/static/", http.StripPrefix("/static/", static))
        http.Handle("/js/", http.StripPrefix("/js/", js))
        // Register function to "/"
        http.HandleFunc("/", indexHandler)
        fmt.Println("Server is starting...")
        err := http.ListenAndServe("0.0.0.0:8181", nil)
        if err != nil {
                log.Fatal("cannot listen and server", err)
        }
        
}
func indexHandler(w http.ResponseWriter, r *http.Request) {
        wd, err := os.Getwd()
        var static = filepath.Join(wd, "static")
        var index = filepath.Join(static, "index.html")
        if err != nil {
                log.Fatal("cannot get working directory", err)
        }

        // Check if the request is an OPTIONS preflight request
        if r.Method == "OPTIONS" {
                // Respond with status OK to preflight requests
                w.WriteHeader(http.StatusOK)
                return
        }

        // POST-Request
        if r.Method == http.MethodPost {
              // do something
        } else {
                // Loading the index.html without any data
                tmpl, err := template.ParseFiles(index)
                err = tmpl.Execute(w, nil) // write response to w
                if err != nil {
                        http.Error(w, err.Error(), http.StatusInternalServerError)
                        log.Fatal("problem with parsing the index template ", err)
                }

        }
}

我的应用程序的 struct 是这样的.

├── web
│   ├── Dockerfile
│   ├── go.mod
│   ├── server.go
│   └── static
│   │   ├── index.html
│   │   ├── style.css
│   │   └── table.html
│   └── js
│       └── htmx.min.js

configuration.nixnginx段的配置如下所示.

  services.nginx = {
    enable = true;
    recommendedGzipSettings = true;
    recommendedOptimisation = true;
    recommendedProxySettings = true;
    recommendedTlsSettings = true;
    virtualHosts."myapp" = {
      sslCertificate = "/etc/ssl/nginx/ssl.cert";
      sslCertificateKey = "/etc/ssl/nginx/ssl.key";
      sslTrustedCertificate = "/etc/ssl/nginx/ssl.chain";
      forceSSL = true; # Redirect HTTP to HTTPS
      locations = {
        "/myapp" = { proxyPass = "http://localhost:8181/"; };
      };
      extraConfig = ''
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      '';
    };

  };

当我寻址URL https://server/myapp时,index.html将加载,但style.csshtmx.min.js将返回404.

当使用端口8181而不是URL(http://server:8181)寻址容器时,一切照常加载.

我希望nginx将加载css和js的请求重定向到容器.

一百零二 准确的错误是:GET https://server.name/static/style.css net::ERR_ABORTED 404,即使我访问的是https://server.name/myapp.

另一个重要信息是,我希望在同一个反向代理上以这种方式运行多个容器.因此,将ALS cssjs文件定向到同一位置是行不通的.

推荐答案

请判断index.html文件中的css/js引用.您很可能通过如下的绝对路径引用它们:

<html>
  <head>
    <link rel="stylesheet" type="text/css" href="/static/style.css" />
    <script src="/js/htmx.min.js"></script>
  </head>
</html>

一个快速的解决办法是用相对路径替换它们:

<html>
  <head>
    <link rel="stylesheet" type="text/css" href="./static/style.css" />
    <script src="./js/htmx.min.js"></script>
  </head>
</html>

这种方法容易出错.更好的方法是修改应用程序,使其以/myapp:

http.Handle("/myapp/static/", http.StripPrefix("/myapp/static/", static))
http.Handle("/myapp/js/", http.StripPrefix("/myapp/js/", js))
http.HandleFunc("/myapp/", indexHandler)

修改index.html文件中的引用路径:

<html>
  <head>
    <link rel="stylesheet" type="text/css" href="/myapp/static/style.css" />
    <script src="/myapp/js/htmx.min.js"></script>
  </head>
</html>

然后修改nginx配置:

locations = {
  "/myapp/" = { proxyPass = "http://localhost:8181/myapp/"; };
};

使用这种方法,无论是否使用反向代理,Web应用程序都将始终在URI /myapp/处提供服务,这应该会使其易于维护.

Go相关问答推荐

Golang Cososdb-gremlin连接

macOS上GoLand 2023.3.4中的代码导航

在Golang中,@LATEST和@UPGRADE特殊查询有什么不同?

如何修复Go中调用GetRawInputDeviceInfA Windows API函数时的错误?

Golang测试容器,无法使网络正常工作

如何使用我的 struct 化日志(log)记录格式使人panic ?

Golang Gorm Fiber - 如何将定义为别名的名称发送到索引模板?

使用 Golang 获取目录磁盘使用情况

我们如何保证取消的上下文会导致 goroutine 终止?

使用goroutines在Golang中验证 struct

从单词中删除特殊字符

从 eBPF LRU 哈希映射中错误驱逐的元素

golang yaml 马歇尔网址

Golang 中的泛型类型转换

如何使用 Docker 引擎 SDK 和 Golang 运行 docker 挂载卷

如何使用 go-playground/validator 编写 snake case 绑定标签?

在 Raspberry Pi4 上下载 Go Mod

GORM GIN 更新查询导致 500 内部服务器错误

为什么 template.ParseFiles() 没有检测到这个错误?

泛型:对具有返回自身的函数的类型的约束