7

我正在使用 Go(使用 Echo)作为后端和 Angular 6 作为前端来设置 Web 服务器。我所做的是使用 Angular-cli 'ng new my-app' 创建一个简单的应用程序,添加一个 helloworld 组件和一个 '/helloworld' 路由,然后使用 'ng build --prod' 将其构建到生产中,输出为 'dist ' 文件夹。文件夹结构:

dist
├── assets
│   ├── icons
│   └── logo.png
├── favicon.ico
├── index.html
├── main.js
├── polyfills.js
├── runtime.js
└── styles.css

然后,我让 Go 使用以下代码 main.go 为该“dist”文件夹中的静态文件提供服务

func main() {
    e := echo.New()
    e.Static("/", "dist")
    e.File("/", "dist/index.html")
    e.Start(":3000")
}

现在,当我使用浏览器并转到“localhost:3000/”时,页面将正确提供,由于 Angular 路由,我可以使用 href 导航,例如:“localhost:3000/home”页面将正确显示但是如果我尝试刷新它,那么 Echo 将返回一个显示的页面内容:

{“未找到信息”}

我知道我可以像这样手动设置路线:

e.File("/home","dist/index.html")

但是,如果我有更多的路线,那么做这一切会很麻烦。

我需要的是任何未为 Echo 定义的路由都将映射到“index.html”。我确实尝试过:

e.File("/*", "dist/index.html")

e.GET("/*", func(c echo.Context) 
    return c.File("dist/index.html")
})

但后来我得到一个有错误的空白页

"Uncaught SyntaxError: Unexpected token <  " 

包含所有 3 个文件 main.js、polyfill.js 和 runtime.js

我是 Echo 的新手,所以我不知道该怎么做。

4

4 回答 4

3

这个问题与 Echo 没有严格的关系。Angular 进行路由的方式是它不向服务器请求页面。它更改 URL 而不实际从服务器请求另一个页面。

因此,当您转到“/home”,然后刷新时,您的浏览器将尝试访问服务器并请求“/home”(与第一次相反,浏览器请求映射到“dist/”的“/” index.html”)。在 Echo 路由中找不到或未定义“/home”。因此,您会收到 Not Found 消息。

我建议您对路由执行以下操作

e.Static("/dist", "dist")
e.File("/*", "dist/index.html")
e.Start(":3000")

并在index.html请求资源的 URL 之前添加“/dist”。

于 2018-12-25T13:06:02.587 回答
2

HTML5echo 中的静态中间件中还有一个选项:例如

e.Use(middleware.StaticWithConfig(middleware.StaticConfig{
        Root:   "dist",
        Index: "index.html",
        Browse: true,
        HTML5:  true,
    }))

这似乎可以处理 SPA 网页。

于 2019-09-20T13:39:28.920 回答
0

@Seaskyways 的回答对我很有用,但在更多地研究 Echo 之后,我也设法找到了另一种解决方案。Echo 有一个 NotFoundHandler 可以处理所有未知的路由,所以我所做的只是让它在每次请求未定义的路由时返回“index.html”。这是我的代码:

echo.NotFoundHandler = func(c echo.Context) 
    return c.File("dist/index.html")
}
e := echo.New()
e.Static("/", "dist")
e.Start(":3000")

我不确定这是否是一种好方法,但对于像我这样有同样问题的人来说,这是另一种选择

于 2018-12-26T04:33:26.030 回答
0

将其留在这里作为替代方案,以防有人想要一个完整的示例。使用“/*”将捕获任何以“/”开头的路由或任何您想要的尚未定义的前缀。

package main

import (
    "github.com/labstack/echo/v4"
    "github.com/labstack/echo/v4/middleware"
)

const (
    HTTP_PORT = ":1234"
)

func main() {
    e := echo.New()

    // Logger Middleware
    e.Use(middleware.Logger())

    // Setup routes
    SetupRoutes(e)

    e.Logger.Fatal(e.Start(HTTP_PORT))
}

func SetupRoutes(e *echo.Echo) {
    // Catpure route /
    e.GET("/", getWebApp)
    
    // Catpure route /test
    e.GET("/test", getTest)
    
    // Catpure all routes starting with / that haven't been defined 
    e.GET("/*", getWebApp)
    
    // Use e.Any() for all request methods GET, PUT, POST, PATCH and DELETE
    e.Any("/*", getWebApp)
}

func getWebApp(ctx echo.Context) error {
    return ctx.File("../website_src/index.html")
}

func getTest(ctx echo.Context) error {
    return ctx.String(http.StatusOK, "Hello")
}
于 2022-02-09T15:30:19.103 回答