Как обслуживать как динамические, так и статические страницы с помощью Dart и shelf?

С помощью 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 дает мне не найдено.

Должен ли я даже не пытаться сделать это с shelf_static? Если нет, то какой будет правильный подход? Спасибо!

3 ответа

Решение

Ты можешь использовать 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}');
});

Причина в том, что shelf_route методы, такие как get должен полностью соответствовать пути. Со статическими файлами вам не нужны точные совпадения, так как оставшаяся часть пути указывает вам путь к файлу.

Для этого вам нужно использовать add метод и набор exactMatch: false как в настоящее время методы, такие как get, post и т. д. не подвергать exactMatch,

Следующие работы

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();
}

addStaticAssetHandler звонки createStaticHandler негласно, но также поддерживает вызов паба в режиме разработки, что очень удобно для таких вещей, как полимер

fallbackHandler можно указать для Router, Похоже, что использование статического обработчика здесь решает проблему.

Router routes = new Router(fallbackHandler: staticHandler)
  ..get('/item/{itemid}', handler.doItem);
Другие вопросы по тегам