我正在try 使用嵌入的单一二进制文件来包含SvelteKit网站.我使用Chi作为我的路由.但我不能让它起作用.我得到了下面这些选项中的一个.据我所知,Embeddall:选项确保包含以_为前缀的文件.我还在Main V1:/uibuild/uibuild/等版本中try 了StripPrefix方法的变体.

有没有人能给它点光?

Sample repo

  1. 目录列表(S),在我的例子中是`uiBuild`
  2. 空白页在"/"但在Chrome控制台404‘S上的嵌套文件
  3. 404在主页"/"上.

Svelte config:

import preprocess from "svelte-preprocess";
import adapter from "@sveltejs/adapter-static";

/** @type {import('@sveltejs/kit').Config} */
const config = {
  kit: {
    adapter: adapter({
      pages: "./../server/uibuild",
      assets: "./../server/uibuild",
      fallback: "index.html",
    }),
  },

  preprocess: [
    preprocess({
      postcss: true,
    }),
  ],
};

export default config;

Main.go V1:

这会给出错误3.

package main

import (
    "embed"
    "log"
    "net/http"

    chi "github.com/go-chi/chi/v5"
)

//go:embed all:uibuild
var svelteStatic embed.FS

func main() {

    r := chi.NewRouter()

    r.Handle("/", http.StripPrefix("/uibuild", http.FileServer(http.FS(svelteStatic))))

    log.Fatal(http.ListenAndServe(":8082", r))
}

Main.go V2:

这将显示错误2.

static, err := fs.Sub(svelteStatic, "uibuild")
    if err != nil {
        panic(err)
    }

r := chi.NewRouter()
r.Handle("/", http.FileServer(http.FS(static)))

log.Fatal(http.ListenAndServe(":8082", r))

File structure:

.
├── go.mod
├── go.sum
├── main.go
└── uibuild
    ├── _app
    │   ├── immutable
    │   │   ├── assets
    │   │   │   ├── 0.d7cb9c3b.css
    │   │   │   └── _layout.d7cb9c3b.css
    │   │   ├── chunks
    │   │   │   ├── index.6dba6488.js
    │   │   │   └── singletons.b716dd01.js
    │   │   ├── entry
    │   │   │   ├── app.c5e2a2d5.js
    │   │   │   └── start.58733315.js
    │   │   └── nodes
    │   │       ├── 0.ba05e72f.js
    │   │       ├── 1.f4999e32.js
    │   │       └── 2.ad52e74a.js
    │   └── version.json
    ├── favicon.png
    └── index.html

推荐答案

令人沮丧的是,您的"Main.Go V2"只需添加一个字符即可.您正在使用:

r.Handle("/", http.FileServer(http.FS(static)))

从文档中:

func (mx *Mux) Handle(pattern string, handler http.Handler)

每个路由方法都接受URL模式和处理程序链.URL模式支持命名参数(即/USERS/{userID})和通配符(即/admin/). URL parameters can be fetched at runtime by calling chi.URLParam(r, "userID") for named parameters and chi.URLParam(r, "")表示通配符参数.

因此,您传入"/"作为"模式";这将匹配/,但不匹配其他;要修复用法:

r.Handle("/*", http.FileServer(http.FS(static)))
// or
r.Mount("/", http.FileServer(http.FS(static)))

我用我的一个超薄应用程序测试了这一点,它运行得很好.您可能想要考虑的一种改进是将对不存在的文件的任何请求重定向到/(否则,如果用户为页面添加书签,则它将无法加载路径).有关信息,请参见this answer.

继续上面的内容--为了演示我在 comments 中所说的,在ui/src/routes/+page.svelte和Rebuild的末尾添加<a href="/about">About</a>(这两个都是Svelte,然后是Go应用程序).然后,您将能够导航到about页(首先加载主页,然后单击"About").这是由客户端路由处理的(因此您可能不会看到对GO服务器的任何请求).有关如何在直接访问页面(例如/about)时使其正常工作的信息,请参阅linked answer.

下面是一个简短的(有点老套的)示例,它将从嵌入式文件系统提供所需的位,并为所有其他请求返回主index.html(以便Svelte路由可以显示所需的页面).

package main

import (
    "embed"
    "fmt"
    "io/fs"
    "log"
    "net/http"

    "github.com/go-chi/chi/v5"
)

//go:embed all:uibuild
var svelteStatic embed.FS

func main() {

    s, err := fs.Sub(svelteStatic, "uibuild")
    if err != nil {
        panic(err)
    }

    staticServer := http.FileServer(http.FS(s))

    r := chi.NewRouter()

    r.Handle("/", staticServer) // Not really needed (as the default will pick this up)
    r.Handle("/_app/*", staticServer)      // Need to serve any app components from the embedded files
    r.Handle("/favicon.png", staticServer) // Also serve favicon :-)

    r.HandleFunc("/*", func(w http.ResponseWriter, r *http.Request) { // Everything else returns the index
        r.URL.Path = "/" // Replace the request path
        staticServer.ServeHTTP(w, r)
    })

    fmt.Println("Running on port: 8082")
    log.Fatal(http.ListenAndServe(":8082", r))
}

Go相关问答推荐

如何使用Docker Compose配置Go,使main. go文件位于/CMD文件夹中

Go-Colly:将数据切片为POST请求

是不是有什么原因导致`Strings.EqualFold`不先进行长度比较?

如何使用Gio设置标题栏图标

确定果朗CSV行中的字节数

go-jwt 令牌验证错误 - 令牌签名无效:密钥类型无效

golang gin 获取 cookie json

当客户端同时是服务器时,需要什么 mTLS 证书?

GoLang:net.LookupHost 返回重复的 ips

Go:如何在将 float64 转换为 float32 时判断精度损失

Gorm 预加载给出了模糊的列错误

GOLANG:为什么 SetDeadline/SetReadDeadline/SetWriteDeadline 在使用 os.File.Fd() 时对文件不起作用?

golang pic.ShowImage 为什么它不生成图像而是向我发送base64值

如何将文件上传到 Google Drive,并与使用服务帐户和 Golang 的任何人共享

如何通过组合来自不同包的接口来创建接口?

Go GCP 同时模拟两个服务帐户

如何正确判断 io.Reader 是否为零?

带有 *s3.S3 对象的 Golang 单元测试

Beego - 我需要context.Context而不是 Beego 上下文

为什么在 unsafe.Sizeof() 中取消引用 nil 指针不会导致panic ?