9

使用shelf_static通过 Dart 提供静态网页是没有问题的:

var staticHandler = createStaticHandler(staticPath, defaultDocument:'home.html');
io.serve(staticHandler, 'localhost', port).then((server) {
  print('Serving at http://${server.address.host}:${server.port}');
});

我可以shelf_route很好地用于动态网页:

Router routes = new Router()
  ..get('/item/{itemid}', handler.doItem);
var handler = const shelf.Pipeline()
  .addHandler(routes.handler);

io.serve(handler, 'localhost', port).then((server) {
  print('Serving at http://${server.address.host}:${server.port}');
});

但我正在努力向动态版本添加静态处理程序。我尝试过的事情包括:

Router routes = new Router()
  ..get('/item/{itemid}', handler.doItem)
  ..get('/', staticHandler);

或者 ...

  ..get('/.*', staticHandler);

或者 ...

  ..get('/{any}', staticHandler);

home.html如果我请求,所有这些都会给我指定的默认页面,http://localhost:8080/但明确要求现有页面http://localhost:8080/home.html给我 Not Found。

我什至不应该尝试这样做shelf_static吗?如果不是,那么正确的方法是什么?谢谢!

4

3 回答 3

12

您可以使用Cascade. 它创建一系列处理程序,如果前一个给出 404 或 405 响应,则移动到下一个。

var staticHandler = createStaticHandler(staticPath, defaultDocument:'home.html');
var routes = new Router()
    ..get('/item/{itemid}', handleItem);

var handler = new Cascade()
    .add(staticHandler)
    .add(routes.hander)
    .handler;
io.serve(handler, 'localhost', port).then((server) {
  print('Serving at http://${server.address.host}:${server.port}');
});
于 2014-12-06T19:50:58.890 回答
6

原因是shelf_route类似的方法get必须完全匹配路径。对于静态文件,您不需要完全匹配,因为路径的其余部分会告诉您文件的路径。

为此,您需要使用该add方法并将其设置exactMatch: false为当前不公开的方法get,例如等。postexactMatch

以下作品

void main(List<String> args) {

  Logger.root.onRecord.listen(print);

  var staticHandler = createStaticHandler('../static', defaultDocument:'home.html');

  final root = router()
    ..get('/item/{itemid}', (Request request) => 'handling the item')
    ..add('/', ['GET'], staticHandler, exactMatch: false);

  printRoutes(root);

  io.serve(root.handler, InternetAddress.ANY_IP_V6, 9999);

}

仅供参考,我添加了一个名为mojito的更高级别的框架,它是许多货架组件上的薄胶层,这使得这更容易一些。

它仍然有点新且记录不充分,但如果您有兴趣,您可以执行以下操作

void main(List<String> args) {

  Logger.root.onRecord.listen(print);

  final app = mojito.init();

  app.router
    ..get('/item/{itemid}', (String itemid) => 'handling the item $itemid')
    ..addStaticAssetHandler('/', fileSystemPath: '../static', 
        defaultDocument:'home.html');

  app.start();
}

addStaticAssetHandlercreateStaticHandler在幕后调用,但也支持在开发模式下调用 pub serve 这对于像聚合物这样的东西非常方便

于 2014-12-08T01:03:39.413 回答
2

可以fallbackHandlerRouter. 似乎在这里使用静态处理程序可以解决问题。

Router routes = new Router(fallbackHandler: staticHandler)
  ..get('/item/{itemid}', handler.doItem);
于 2014-12-06T14:34:39.363 回答