flutter web(托管在 nodejs 中)在使用 setPathUrlStrategy 时无法手动导航到其他页面(从 url 中删除 #)
flutter web(hosted in nodejs) unable to navigate to other page manually when using setPathUrlStrategy (remove # from url)
我正在构建一个 flutter web 来分别为不同的页面提供服务,页面之间没有内部导航,用户在您手动输入 url 时单独访问页面。我使用 setPathUrlStrategy (url_strategy: ^0.2.0) 删除了 url 中的#。每个页面都会有各种路径查询参数,我使用 Uri.base.queryParameters["param1"] 来获取查询参数值。所有这些在我的开发本地主机上都运行良好。但是当部署到生产环境时,我使用 nodejs 来托管我的 flutter web 应用程序,如 https://blog.logrocket.com/flutter-web-app-node-js/ 中所述。网络只能加载登陆页面(例如 myweb.com/home),当我手动输入 url(例如 myweb.com/registration)时,我收到错误消息“无法获取/注册”
我已尝试按照此处所述添加 .htaccess(如下所示)(unable to navigate in flutter web by changing url after removing # from the url),但这根本没有帮助。
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.html?path= [NC,L,QSA]
我相信有某种 url 重写我需要在某个地方编码,在 flutter web 或托管 flutter web 的 nodejs 中?
那么我怎样才能让它工作?
这是托管 flutter web 应用程序的 nodejs 代码
(../build/web是flutter web release版本所在的文件夹)
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, '../build/web')));
var http = require('http');
var port = normalizePort('10810');
app.set('port', port);
var server = http.createServer(app);
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
return val;
}
if (port >= 0) {
return port;
}
return false;
}
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
console.log('Listening on ' + bind);
}
flutter 网页代码:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:mycode/page/page_home.dart';
import 'package:mycode/page/page_reg.dart';
import 'package:mycode/page/page_status.dart';
import 'package:url_strategy/url_strategy.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
setPathUrlStrategy();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
String initRoute = PageReg.routeName;
return GetMaterialApp(
navigatorKey: navigatorKey,
debugShowCheckedModeBanner: false,
title: 'EDDA Registration',
initialRoute: PageHome.routeName,
getPages: [
GetPage(name: PageReg.routeName, page: () => PageReg()),
GetPage(name: PageStatus.routeName, page: () => PageStatus()),
GetPage(name: PageHome.routeName, page: () => PageHome()),
],
);
}
}
您的快递服务器的路由设置似乎不正确。当您尝试访问“/registration”时,您的快速服务器正在尝试进行路由而不是您的 Flutter/web 应用程序,因此您会收到 Cannot GET /registration
错误消息,我认为这也是 return正在处理 404 状态代码,因为它不存在。
最简单的解决方案是将来自您的快速服务器的所有 GET 请求设置为 return 网络应用程序并在其中处理路由。理想情况下,路由应该完成 server-side 但在这种情况下,您正试图在您的网络应用程序中处理它。
尝试在第 9 行之后添加此代码并重新启动您的 Express 应用程序,这将 return 您的 Fluter Web 应用程序在每次 GET 请求到您的 Express 服务器时,然后您就可以在您的 Web 应用程序中处理路由(记住也可以在您的 Flutter 网络应用中添加 404/routing not found 页面!)
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, '../build/web')));
app.get('*', (_, res) => {
res.sendFile(path.resolve(__dirname, '../build/web/index.html'));
});
我正在构建一个 flutter web 来分别为不同的页面提供服务,页面之间没有内部导航,用户在您手动输入 url 时单独访问页面。我使用 setPathUrlStrategy (url_strategy: ^0.2.0) 删除了 url 中的#。每个页面都会有各种路径查询参数,我使用 Uri.base.queryParameters["param1"] 来获取查询参数值。所有这些在我的开发本地主机上都运行良好。但是当部署到生产环境时,我使用 nodejs 来托管我的 flutter web 应用程序,如 https://blog.logrocket.com/flutter-web-app-node-js/ 中所述。网络只能加载登陆页面(例如 myweb.com/home),当我手动输入 url(例如 myweb.com/registration)时,我收到错误消息“无法获取/注册”
我已尝试按照此处所述添加 .htaccess(如下所示)(unable to navigate in flutter web by changing url after removing # from the url),但这根本没有帮助。
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.html?path= [NC,L,QSA]
我相信有某种 url 重写我需要在某个地方编码,在 flutter web 或托管 flutter web 的 nodejs 中?
那么我怎样才能让它工作?
这是托管 flutter web 应用程序的 nodejs 代码 (../build/web是flutter web release版本所在的文件夹)
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, '../build/web')));
var http = require('http');
var port = normalizePort('10810');
app.set('port', port);
var server = http.createServer(app);
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
return val;
}
if (port >= 0) {
return port;
}
return false;
}
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
console.log('Listening on ' + bind);
}
flutter 网页代码:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:mycode/page/page_home.dart';
import 'package:mycode/page/page_reg.dart';
import 'package:mycode/page/page_status.dart';
import 'package:url_strategy/url_strategy.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
setPathUrlStrategy();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
String initRoute = PageReg.routeName;
return GetMaterialApp(
navigatorKey: navigatorKey,
debugShowCheckedModeBanner: false,
title: 'EDDA Registration',
initialRoute: PageHome.routeName,
getPages: [
GetPage(name: PageReg.routeName, page: () => PageReg()),
GetPage(name: PageStatus.routeName, page: () => PageStatus()),
GetPage(name: PageHome.routeName, page: () => PageHome()),
],
);
}
}
您的快递服务器的路由设置似乎不正确。当您尝试访问“/registration”时,您的快速服务器正在尝试进行路由而不是您的 Flutter/web 应用程序,因此您会收到 Cannot GET /registration
错误消息,我认为这也是 return正在处理 404 状态代码,因为它不存在。
最简单的解决方案是将来自您的快速服务器的所有 GET 请求设置为 return 网络应用程序并在其中处理路由。理想情况下,路由应该完成 server-side 但在这种情况下,您正试图在您的网络应用程序中处理它。
尝试在第 9 行之后添加此代码并重新启动您的 Express 应用程序,这将 return 您的 Fluter Web 应用程序在每次 GET 请求到您的 Express 服务器时,然后您就可以在您的 Web 应用程序中处理路由(记住也可以在您的 Flutter 网络应用中添加 404/routing not found 页面!)
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, '../build/web')));
app.get('*', (_, res) => {
res.sendFile(path.resolve(__dirname, '../build/web/index.html'));
});