flutter web中url路由模式以及参数传递

Flutter开发中,项目中我使用Get库进行路由管理状态管理。其页面跳转使用Get.toNamed()的方式是比较方便的,参数传递方式也比较简单,例如

Get.toNamed(
    AppRouters.myOrderList,
    arguments: {
        "fromExternal": true,
        "orderStatus": 2
    }
);

可以在对应页面的Controller中onInit方法中,获取到传递过来的参数。

在web的场景中,情况会变得稍微有点复杂。 在web中除了页面跳转以及参数传递外,它的每个页面都有个对应的url,用户可以通过浏览器直接访问到某一个指定的页面,跟App相比,这点就脱离了程序的本身的掌控范围。直接通过Url来进入到指定页面,就需要可以通过URL传递参数的需求。

Flutter Web中的路由模式

Flutter Web应用支持两种基于URL的路由配置方式:Hash(默认) 和 Path。

1. Hash(默认)

路径使用 # + 锚点标识符 读写,例如 flutterexample.dev/#/path/to/screen

2. Path

路径使用非 # 读写,例如 flutterexample.dev/path/to/screen

不管使用的是Hash模式还是Path模式,其参数传递的方式都是相同的。如果也是使用Get来做路由管理的话,在依赖注入的设置中,GetPage设置如下

GetPage(
  name: "/deviceDetail/:deviceId",
  page: () => const DeviceDetailPage(),
  binding: DeviceDetailBinding(),
),

其中name设置的/deviceDetail/:deviceId:deviceId就代表设备id的参数。在浏览器中url中通过链接 http://localhost:8080/deviceDetail/123456这样的方式就可以进入到指定页面,并可以在对应的页面中的controller中获取到这个参数。

注意:与上述Get.toNamed()arguments传递参数不同,通过Url路径传递参数的话,需要使用Get.parameters才能获取到对应的参数。 而Get.toNamed()方法中,通过arguments参数传递的参数,则需要通过Get.arguments来获取参数。

# Hash模式转为Path模式

在web中,浏览器中的Url使用Hash模式,也就是带有 # 的url的方式其实并不常见。有时候会感觉这种方式比较奇怪,那么是否可以去掉这个 # 呢?当然可以的。

方式很简单,使用一个插件 url_strategy ,稍加配置就可以实现这个功能。

url_strategy 的使用

安装好插件后,配置方式如下,只需要设置 setPathUrlStrategy();

import 'package:url_strategy/url_strategy.dart';

void main() {
  // Here we set the URL strategy for our web app.
  // It is safe to call this function when running on mobile or desktop as well.
  setPathUrlStrategy();
  runApp(MyApp());
}

除了这个之外,还需要在项目的web目录下,在web/index.html<head>标签中,添加

<base href="/">

如果在web/index.html<head>标签中有设置<base href="$FLUTTER_BASE_HREF">,将其去掉。换为<base href="/">

这时候,就完成了Url中去掉#的工作。

去掉 # 后,上线后问题,Nginx配置的修改

上述修改完成后,用Android stdio等工具进行调试时,发现没有什么问题。但是当项目打包放在服务器下面进行访问的时候,你会发现出现一个奇怪的问题。正常从首页开始,一步步点击测试的时候没有任何问题,但是,当直接通过url访问一个非首页的页面时,会出现404 not found的错误。

这是因为Nginx的配置不支持单页应用(SPA)的路由导致的。为了解决这个问题,则需要对Nginx的配置进行修改。

在服务器块内,添加以下配置

location / {
    try_files $uri $uri/ /index.html;
}

这个配置告诉Nginx,当请求的Url不存在时,返回index.html文件。这将允许Flutter Web应用处理所有的路由请求。

然后重启Nginx服务使配置生效。至此,线上的Flutter Web也可以正常访问对应的页面。

Comments

No comments yet. Why don’t you start the discussion?

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注