You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Web使用go_router重载报Cannot set URL strategy more than once错误

问题产生原因

你将GoRouter实例的初始化逻辑写在了StatelessWidget的build方法中。Flutter框架在页面重载、热重载、组件树重绘时,会反复执行build方法,每次执行都会生成全新的GoRouter实例。当你给GoRouter配置了urlPathStrategy: UrlPathStrategy.path时,实例初始化阶段会调用Flutter Web的全局URL策略设置接口,而这个接口有全局校验,整个应用生命周期内只允许设置一次URL策略,重复调用就会抛出你看到的:

Assertion failed: org-dartlang-sdk:///flutter_web_sdk/lib/_engine/engine/window.dart:25:10
!_isUrlStrategySet
"Cannot set URL strategy more than once."

首次加载页面时build仅执行一次,路由初始化正常,所以返回按钮功能可以正常运行;一旦触发页面重载,build再次执行就会重复初始化路由触发报错。

修复方案

两种修复方式二选一即可,核心原则是保证GoRouter实例和URL策略配置全局仅执行一次,不要放在build生命周期内。

  • 方案1:调整现有代码结构,将GoRouter实例从build方法中提取为类的静态常量/成员,不会随build执行重复创建。
    修改后的完整代码示例:
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:navigator_2/some_app.dart';

import 'details_page.dart';

void main() {
  runApp(const MyApp());
}


class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // 路由实例作为类静态属性,全局仅初始化一次
  static final GoRouter _router = GoRouter(
    urlPathStrategy: UrlPathStrategy.path,
    routes: [
      GoRoute(path: '/',builder: (context,state)=> const SomeAppPage()),
      GoRoute(path: '/details',builder: (context,state){
        final query = state.queryParams['index'];
        return DetailsPage(index: int.parse(query!));
      }),
    ],
  );

  @override
  Widget build(BuildContext context) {
    return  MaterialApp.router(
      routeInformationParser: _router.routeInformationParser,
      routerDelegate: _router.routerDelegate ,
      title: 'Go Router Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
    );
  }
}
  • 方案2:如果你使用的是go_router 5.0及以上的新版本,官方已经废弃了GoRouter构造函数中的urlPathStrategy入参,要求在main函数中runApp调用前全局配置一次URL策略,从写法上避免重复设置的问题。
    对应代码示例:
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:navigator_2/some_app.dart';

import 'details_page.dart';

void main() {
  // Web环境下全局仅调用一次URL策略配置,写在runApp之前
  if (kIsWeb) {
    GoRouter.setUrlPathStrategy(UrlPathStrategy.path);
  }
  runApp(const MyApp());
}


class MyApp extends StatelessWidget {
  const MyApp({super.key});

  static final GoRouter _router = GoRouter(
    // 新版本移除了构造函数内的urlPathStrategy配置项
    routes: [
      GoRoute(path: '/',builder: (context,state)=> const SomeAppPage()),
      GoRoute(path: '/details',builder: (context,state){
        final query = state.queryParams['index'];
        return DetailsPage(index: int.parse(query!));
      }),
    ],
  );

  @override
  Widget build(BuildContext context) {
    return  MaterialApp.router(
      routeInformationParser: _router.routeInformationParser,
      routerDelegate: _router.routerDelegate ,
      title: 'Go Router Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
    );
  }
}

注意:不要将路由实例放在build方法内创建,除了触发本次的URL策略报错,还可能导致路由状态丢失、不必要的性能损耗。


内容的提问来源于stack exchange,提问作者Divyam Makar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 07:39:20