如何让 golang 重定向到前端路由?

use*_*010 8 go reactjs react-router

目前我正在使用以下设置为我的 React 应用程序提供服务

func main() {
    http.Handle("/", http.FileServer(http.Dir("./build/")))
    http.HandleFunc("/my_api", handler)
    http.ListenAndServe(":8090", nil)
}
Run Code Online (Sandbox Code Playgroud)

和前端

function App() {
  return (
    <Router>
      <div>
        <nav>
          <ul>
            <li>
              <Link to="/">Home</Link>
            </li>
            <li>
              <Link to="/my_frontend_path">MyPath</Link>
            </li>
          </ul>
        </nav>

        <Switch>
          <Route path="/my_frontend_path">
            <MyPath />
          </Route>
          <Route path="/">
            <Home />
          </Route>
        </Switch>
      </div>
    </Router>
  );
}
Run Code Online (Sandbox Code Playgroud)

但是当我直接http://localhost:8090/my_frontend_path从浏览器访问golang 返回时404 page not found,有没有办法将任何不支持的路径委托main给默认前端反应路由器?

Bri*_*its 8

此问题的答案中详细介绍了您遇到的问题。值得仔细阅读答案(特别是已接受的答案),因为有一系列选项(具有不同的缺点)。

基本问题是,当您向http://localhost:8090/my_frontend_path前端发出初始请求时,反应路由器未运行,因此浏览器从服务器请求页面;因为文件夹my_frontend_path中不存在会返回错误。buildhttp.FileServer404 page not found

我怀疑对您来说最简单的解决方案可能是使用哈希历史记录(在接受的答案中涵盖)。

然而,由于您提供了一些 Go 服务器端代码,因此有一个相当简单的、纯粹服务器端的选项。“包罗万象”方法的工作原理是返回index.html(以及您的应用程序)未在其他地方处理的任何路径。这意味着您的应用程序将被加载,并且路由器应该检测my_frontend_path并采取相应的行动(这就是返回内容index.html而不是重定向的原因)。实现这一点的一种简单方法是:

const FSPATH = "./build/"

func main() {
    fs := http.FileServer(http.Dir(FSPATH))

    http.HandleFunc("/my_api", func(w http.ResponseWriter, _ *http.Request) { w.Write([]byte("API CALL")) })
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        // If the requested file exists then return if; otherwise return index.html (fileserver default page)
        if r.URL.Path != "/" {
            fullPath := FSPATH + strings.TrimPrefix(path.Clean(r.URL.Path), "/")
            _, err := os.Stat(fullPath)
            if err != nil {
                if !os.IsNotExist(err) {
                    panic(err)
                }
                // Requested file does not exist so we return the default (resolves to index.html)
                r.URL.Path = "/"
            }
        }
        fs.ServeHTTP(w, r)
    })
    http.ListenAndServe(":8090", nil)
}
Run Code Online (Sandbox Code Playgroud)

index.html正如所写的,如果文件不存在,这将返回 的内容- 这包括favicon.ico. 如果这是一个问题,您可能需要添加一些限制(例如检查扩展)。