Flutter虚拟目录服务插件shelf_virtual_directory的使用

发布于 1周前 作者 yuanlaile 来自 Flutter

Flutter虚拟目录服务插件shelf_virtual_directory的使用

简介

shelf_virtual_directory 是一个用于 Dart 的 Shelf 服务器的插件,它提供了 HandlerRouterCascade 来从文件系统中提供静态文件,并且可以与 WebSockets 一起工作。这个插件可以帮助你轻松地为你的 Shelf 服务器设置静态文件服务。

安装

  1. 添加依赖
    pubspec.yaml 文件中添加 shelf_virtual_directory 依赖:

    dependencies:
      shelf_virtual_directory: latest_version
    
  2. 获取依赖
    运行以下命令来获取依赖:

    pub get
    
  3. 导入库
    在 Dart 文件中导入 shelf_virtual_directorypath 包:

    import 'package:shelf_virtual_directory/shelf_virtual_directory.dart';
    import 'package:path/path.dart' as p;
    
  4. 创建 ShelfVirtualDirectory 实例
    创建一个 ShelfVirtualDirectory 实例,指定要提供的静态文件所在的目录(例如 web 目录),并设置默认的索引文件和 404 页面:

    final fsPath = p.join(Directory.current.path, 'example', 'web'); // 服务器文件路径
    final virtualDir = ShelfVirtualDirectory(
      fsPath,
      defaultFile: 'index.html', // 默认索引文件
      default404File: '404.html', // 404 页面
    );
    

    注意:index.html404.html 文件必须直接放在根目录下。在上面的例子中,应该放在 web/ 目录下。

使用场景

1. 作为 Handler 使用

你可以将 ShelfVirtualDirectory 作为 Handler 使用,将其添加到 Pipeline 中,以便在请求时处理静态文件:

final virDirHandler = ShelfVirtualDirectory(fsPath).handler;

final staticFileHandler = const Pipeline()
    .addMiddleware(logRequests()) // 添加日志中间件
    .addHandler(virDirHandler); // 使用作为处理器

await io.serve(Cascade().add(staticFileHandler).handler, address, port)
    .then((server) {
  print('Server is running at ${server.address}:${server.port}');
});
2. 作为 Router 使用

你可以将 ShelfVirtualDirectory 作为 Router 的子路由挂载,这样可以在不同的路径下提供静态文件:

// 作为子路由挂载
final router = Router()
  ..get('/otherroute', otherRouteHandler) // 其他路由
  ..mount('/', ShelfVirtualDirectory(fsPath).router); // 挂载到根路径 (localhost:8080/)

// 或者挂载到特定路径
final router = Router()
  ..get('/otherroute', otherRouteHandler)
  ..mount('/home/', ShelfVirtualDirectory(fsPath).router); // 挂载到 /home/ 路径 (localhost:8080/home/)

// 注意:如果你打算在根目录 ('/') 下使用 `ShelfVirtualDirectory`,请确保将其挂载或处理到最后。
final mainRoute = Router()
  ..get('/rest', (_) => Response.ok('Other routes'))
  ..mount('/', ShelfVirtualDirectory(fsPath).router);
3. 作为 Cascade 使用

你也可以将 ShelfVirtualDirectory 作为 Cascade 使用,直接在服务器中添加其他处理器:

import 'package:shelf/shelf_io.dart' as io show serve;

// 你可以在此处添加其他处理器
final virDirCascade = ShelfVirtualDirectory(fsPath).cascade;
await io.serve(virDirCascade.add(someOtherHandler), 'localhost', 8080)
    .then((server) {
  print('Server is running at ${server.address}:${server.port}');
});

限制

  • 只有 mount 方法支持用于 Router。例如:
    final router = Router()
        ..mount('/home/', virDir.handler)
        ..get('/api', apiHandler);
    

完整示例代码

以下是一个完整的示例代码,展示了如何使用 shelf_virtual_directory 提供静态文件服务:

import 'dart:io';

import 'package:path/path.dart' as p;
import 'package:shelf/shelf.dart' show Pipeline, Response, logRequests;
import 'package:shelf/shelf_io.dart' as io show serve;
import 'package:shelf_router/shelf_router.dart';
import 'package:shelf_virtual_directory/shelf_virtual_directory.dart';

Future<void> main(List<String> args) async {
  // 静态文件目录
  const folderToServe = 'web';
  final address = InternetAddress.loopbackIPv4;
  final port = int.parse(Platform.environment['PORT'] ?? '8082');

  // 创建 [ShelfVirtualDirectory] 实例并提供 [Router] 实例
  final folderPath = p.join(
    Directory.current.path,
    'example',
    folderToServe,
  );
  final virDir = ShelfVirtualDirectory(folderPath);

  // 定义路由
  final apiRouter = Router()
    ..mount('/routerstatic/', virDir.router) // 挂载到 /routerstatic/
    ..mount('/mountstatic/', virDir.handler) // 挂载到 /mountstatic/
    ..mount('/nodirlisting/',
        ShelfVirtualDirectory(folderPath, listDirectory: false).handler) // 禁用目录列表
    ..get('/getstatic/', virDir.handler) // GET 请求 /getstatic/
    ..get('/api/user', (_) => Response.ok('/api/user')) // GET 请求 /api/user
    ..get('/api', (_) => Response.ok('/api')) // GET 请求 /api
    ..mount('/', virDir.handler); // 挂载到根路径

  // 使用 [Pipeline] 添加日志中间件
  final pipeline = const Pipeline().addMiddleware(logRequests()).addHandler(apiRouter);

  // 启动服务器
  final server = await io.serve(
    pipeline,
    address,
    port,
  );

  print('Server is running at http://${server.address.host}:${server.port}');
}

更多关于Flutter虚拟目录服务插件shelf_virtual_directory的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter虚拟目录服务插件shelf_virtual_directory的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用shelf_virtual_directory插件的示例代码。shelf_virtual_directory是一个用于创建虚拟目录服务的Dart包,通常用于后端服务中。由于Flutter本身主要用于前端开发,这个包更可能是在Flutter项目中的Dart后端服务部分使用。

首先,你需要在你的Dart项目中添加shelf_virtual_directory依赖。假设你正在使用pubspec.yaml管理你的Dart依赖(注意,这不是Flutter的pubspec.yaml,而是Dart项目的),你可以添加以下依赖:

dependencies:
  shelf: ^1.0.0  # shelf是一个用于创建HTTP服务器的库
  shelf_virtual_directory: ^x.y.z  # 替换x.y.z为最新版本号

然后,你可以使用以下Dart代码来创建一个简单的HTTP服务器,该服务器使用shelf_virtual_directory来提供一个虚拟目录服务:

import 'dart:io';

import 'package:shelf/shelf.dart';
import 'package:shelf_router/shelf_router.dart';
import 'package:shelf_virtual_directory/shelf_virtual_directory.dart';

void main() async {
  // 创建一个虚拟目录,这里我们使用内存中的字符串作为文件内容
  var files = {
    'index.html': '<html><body><h1>Hello, Shelf Virtual Directory!</h1></body></html>',
    'about.txt': 'This is an about page.',
  };

  var virtualDirectory = VirtualDirectory.inMemory(files);

  // 创建一个Router
  var router = Router()
    ..get('/(*path)', handler: (Request request) async {
      // 使用虚拟目录处理请求
      var response = await virtualDirectory.serveRequest(request);
      return response ?? Response.notFound();
    });

  // 创建一个Handler,将所有请求路由到Router
  var handler = Handler.handlerFunc((Request request) async {
    return await router.handle(request);
  });

  // 启动服务器
  var server = await shelf.serve(handler, 'localhost', 8080);

  print('Serving at http://${server.address.host}:${server.port}');
}

在这个示例中,我们做了以下几件事:

  1. 使用shelf库创建一个HTTP服务器。
  2. 使用shelf_router库创建一个路由器来管理路由。
  3. 使用shelf_virtual_directory库创建一个虚拟目录,其中包含了内存中的文件。
  4. 将所有GET请求路由到虚拟目录服务,如果请求的文件存在,则返回相应的内容;否则返回404 Not Found响应。
  5. 启动服务器并监听localhost的8080端口。

现在,你可以运行这个Dart程序,并在浏览器中访问http://localhost:8080/index.htmlhttp://localhost:8080/about.txt来查看虚拟目录服务提供的内容。

请注意,由于Flutter项目通常不包括直接的后端服务代码,这个示例更适合于Dart后端项目。如果你确实需要在Flutter应用中与后端服务交互,你可能需要创建一个独立的Dart后端服务,并使用Flutter的HTTP客户端库(如diohttp)来与后端进行通信。

回到顶部