【问题标题】:How to have static HTML sites in a flutter web application?如何在 Flutter Web 应用程序中拥有静态 HTML 站点?
【发布时间】:2021-07-12 17:01:18
【问题描述】:

我在 Flutter Web 中有一个项目,我想为它创建一个纯 HTML 的登录页面以用于 SEO 目的。 我的目的是创建一个服务于具有更高优先级的静态文件的服务器,如果静态 HTML 文件会在请求中返回错误,则应使用构建的 Flutter Web 项目作为后备。

我在 Golang 中创建了这个服务器:

package main

import (
    "net/http"
)

func main() {
    http.ListenAndServe(":2000", professionalServer{})
}

type professionalServer struct{}

var flutterServer = http.FileServer(http.FileSystem(http.Dir("../../../professional/build/web")))
var staticServer = http.FileServer(http.FileSystem(http.Dir("../../../professional/landing-page/dist")))

func (professionalServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    res := preflightResponseWriter{OutputData: make(map[string]int)}
    staticServer.ServeHTTP(res, r)
    if res.OutputData["status_code"] == 200 {
        staticServer.ServeHTTP(w, r)
    } else {
        flutterServer.ServeHTTP(w, r)
    }
}

type preflightResponseWriter struct {
    OutputData map[string]int
}

func (preflightResponseWriter) Header() http.Header {
    return http.Header{}
}

func (preflightResponseWriter) Write([]byte) (int, error) {
    return 0, nil
}

func (p preflightResponseWriter) WriteHeader(statusCode int) {
    p.OutputData["status_code"] = statusCode
}

这实际上可行,但问题是 Flutter Web 使用哈希格式作为路由(即http://website.com/#/dashboard)并且浏览器不发送哈希标签之后的部分,所以我的 golang 服务器看到http://website.com/,然后它检查静态文件服务器是否可以处理这个 URL,它可以,所以静态文件服务器发送响应。

我该如何解决这个问题?是否可以将完整的 URL 发送到服务器,包括 # 之后的部分?

提前感谢您的帮助!

受@ResamVi 的建议启发,我是如何解决它的: 我按照答案中的步骤操作,以便我的应用程序最终具有基本 href /app/。

然后,为了使服务器正常工作,我对我的服务器文件进行了这些更改:

package main

import (
    "net/http"
    "strings"
)

func main() {
    http.ListenAndServe(":2000", professionalServer{})
}

type professionalServer struct{}

var flutterServer = http.StripPrefix("/app/", http.FileServer(http.FileSystem(http.Dir("../../../professional/build/web"))))
var staticServer = http.FileServer(http.FileSystem(http.Dir("../../../professional/landing-page/dist")))

func (professionalServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    if strings.HasPrefix(r.URL.Path, "/app") {
        rw := preflightResponseWriter{OutputData: make(map[string]int)}
        flutterServer.ServeHTTP(rw, r)
        if rw.OutputData["status_code"] >= 400 && rw.OutputData["status_code"] < 500 {
            http.ServeFile(w, r, "../../../professional/build/web/index.html")
        } else {
            flutterServer.ServeHTTP(w, r)
        }
    } else {
        staticServer.ServeHTTP(w, r)
    }
    // check if starts with /app
    // if no -> staticServer
    // if yes:
    //      simulate request, check if response code is ok
    //      if response code is ok, serve via flutterServer.Serve
    //      else serve file directly
}

type preflightResponseWriter struct {
    OutputData map[string]int
}

func (preflightResponseWriter) Header() http.Header {
    return http.Header{}
}

func (preflightResponseWriter) Write([]byte) (int, error) {
    return 0, nil
}

func (p preflightResponseWriter) WriteHeader(statusCode int) {
    p.OutputData["status_code"] = statusCode
}

现在,以 /app 开头的请求将为 Flutter Web 应用加载资产,或者,如果没有资产满足请求,则将加载 index.html。 如果请求 URL 不以 /app 开头,则提供静态文件。

【问题讨论】:

    标签: flutter http go flutter-web


    【解决方案1】:

    这可能更适合作为评论,我会询问您是否要更改网络应用程序的 URL strategy 但我没有代表(请原谅我的主,但这条规则有点限制)

    如果您可以随意更改 URL 策略,您可以通过在上面链接中描述的适当位置添加依赖项来实现:

    import 'package:url_strategy/url_strategy.dart';
    
    void main() {
      setPathUrlStrategy();
      runApp(MyApp());
    }
    

    另请参阅:How to remove hash (#) from URL in Flutter web

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-16
      • 1970-01-01
      • 2019-08-30
      • 2020-06-23
      • 1970-01-01
      • 2023-01-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多