Rocket CORS 如何使用 Request Guard return 字符串?

Rocket CORS how to return string with Request Guard?

我有火箭(0.5.0-rc.1) route, that returns a content::Json<String> and I would like to add CORS to that route using rocket_cors(来自大师)。

具体来说,我想使用 RequestGuard,因为我只想为某些路由启用 CORS。

我最初的请求是这样的:

#[get("/json")]
fn json_without_cors() -> content::Json<String> {
    let test = Test {
        field1: 0,
        field2: String::from("Test"),
    };
    let json = serde_json::to_string(&test).expect("Failed to encode data.");

    content::Json(json)
}

然后我将其更改为使用 CORS(基于此 example),就像这样

#[get("/json")]
fn json(cors: Guard<'_>) -> Responder<'_, '_, content::Json<String>> {
    let test = Test {
        field1: 0,
        field2: String::from("Test"),
    };
    let json = serde_json::to_string(&test).expect("Failed to encode data.");

    cors.responder(content::Json(json))
}

不幸的是,现在无法编译:

error[E0621]: explicit lifetime required in the type of `cors`
  --> src/main.rs:35:10
   |
28 | fn json(cors: Guard<'_>) -> Responder<'_, '_, content::Json<String>> {
   |               --------- help: add explicit lifetime `'static` to the type of `cors`: `Guard<'static>`
...
35 |     cors.responder(content::Json(json))
   |          ^^^^^^^^^ lifetime `'static` required

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0621, E0759.
For more information about an error, try `rustc --explain E0621`.
error: could not compile `cors_json`

我不能给 Guard 一个 'static 生命周期,因为这会导致未来出现更多问题。

如何通过 CORS 从我的请求中 return content::Json<String>

可以在 Github 上找到完整的示例。

我能解决它的唯一方法是反复试验,但我们开始吧:

fn json(cors: Guard<'_>) -> Responder<'_, 'static, content::Json<String>>

这是因为 rocket_corsResponder 结构上有生命周期界限,这使得结构在这些生命周期界限上是协变的(因此它拒绝 'static不应该的生命周期)。

好消息是这些边界在结构的声明中不是必需的,因为它们可以单独存在于相关的 impl 块中。

我已经 created a pull request,但这将是一个突破性的 API 变化,因为 Responder 将不再 直接 泛化这些一生。如果你想继续跟踪他们的主分支,你可以按照@Hadus 的建议并传递一个 'static 作为 Responder 的生命周期参数。

使用PR的分支你可以直接做:

#[get("/json")]
fn json(cors: Guard<'_>) -> Responder<content::Json<String>> {
    let test = Test {
        field1: 0,
        field2: String::from("Test"),
    };
    let json = serde_json::to_string(&test).expect("Failed to encode data.");

    cors.responder(content::Json(json))
}

更新:已合并。