1

ポートフォリオ Web サイトを作成しています。一部のプロジェクトには、URL の ID に従って提供したい静的な HTML デモがあります。ルートは次のようになります。

#[get("/demo/<id>/<pathbuf..>")]
fn site_demo(id: usize, pathbuf: Option<PathBuf>) -> Option<NamedFile> {
    // set path according to id
    let demo = format!{"static/projects/{:03}/demo/", id};
    // if `pathbuf` is not provided, set file to `index.html`
    let pathbuf = pathbuf.unwrap_or(PathBuf::from("index.html"));

    let path = Path::new(&demo).join(pathbuf);
    NamedFile::open(path).ok()
}

ブラウザーに入力localhost:5050/demo/003/index.htmlすると、デモ (およびデモ フォルダー内の他のすべて) が読み込まれます。ただし、入力するlocalhost:5050/demo/003/と、このエラーが発生します(/最後になくても同じ結果になります):

GET /demo/003/ text/html:
    => Error: No matching routes for GET /demo/003/ text/html.
    => Warning: Responding with 404 Not Found catcher.
    => Response succeeded.

PathBufはオプションであり、 に設定されるため、ルートが一致することを期待していindex.htmlます。私には理にかなっています...

どこかで間違っていましたか、それとも問題を開く必要がありますか?

4

1 に答える 1

0

複数セグメントのパスを空にすることはできません。

別のアプローチは、2 つのルートを使用することです。

  • 複数セグメント用の 1 つ/demo/<id>/<pathbuf..>
  • /demo/<id>にリダイレクトする空のセグメント用の 1 つ/demo/<id>/index.html

ruby nightlyと rocket 0.4を使用したサンプル:

#![feature(proc_macro_hygiene, decl_macro)]  
#[macro_use] extern crate rocket;

use std::path::{Path,PathBuf};
use rocket::response::{Redirect,NamedFile};

#[get("/demo/<id>/<pathbuf..>")]
fn site_demo(id: usize, pathbuf: PathBuf) -> Option<NamedFile> {
    let demo = format!{"static/projects/{:03}/demo/", id};
    NamedFile::open(Path::new(&demo).join(pathbuf)).ok()
}

#[get("/demo/<pathbuf..>", rank=2)]
fn redirect(pathbuf: PathBuf) -> Redirect {
    Redirect::to(format!{"/demo/{}/index.html", pathbuf.display()})
}

fn main() {
    rocket::ignite().mount("/", routes![site_demo,redirect]).launch();
}

安定とロケット0.5を使用したサンプル:

#[macro_use] extern crate rocket;

use std::path::{Path,PathBuf};
use rocket::response::{Redirect,NamedFile};

#[get("/demo/<id>/<pathbuf..>")]
async fn site_demo(id: usize, pathbuf: PathBuf) -> Option<NamedFile> {
    let demo = format!{"static/projects/{:03}/demo/", id};
    NamedFile::open(Path::new(&demo).join(pathbuf)).await.ok()
}

#[get("/demo/<pathbuf..>", rank=2)]
fn redirect(pathbuf: PathBuf) -> Redirect {
    Redirect::to(format!{"/demo/{}/index.html", pathbuf.display()})
}

#[launch]
fn rocket() -> rocket::Rocket {
    rocket::ignite().mount("/", routes![site_demo,redirect])
}

このlocalhost:5050/demo/003/ようにリダイレクトされてからlocalhost:5050/demo/003/index.htmlロードlocalhost:5050/demo/003/index.htmlされますstatic/projects/003/demo/index.html

于 2019-08-10T10:26:11.220 に答える