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

Posted

技术标签:

【中文标题】Rocket CORS 如何使用 Request Guard 返回字符串?【英文标题】:Rocket CORS how to return string with Request Guard? 【发布时间】:2021-09-12 11:29:43 【问题描述】:

我有一个火箭 (0.5.0-rc.1) 路线,它返回一个 content::Json<String>,我想使用 rocket_cors(来自 master)将 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 请求中返回 content::Json&lt;String&gt;

完整的例子可以在Github找到。

【问题讨论】:

【参考方案1】:

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

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

我有 created a pull request,但这将是一个破坏性的 API 更改,因为 Responder 在这些生命周期内将不再直接通用。如果你想继续跟踪他们的主分支,你可以按照@Hadus 的建议做,并传递一个'static 作为响应者的生命周期参数。

使用 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))

更新:已合并。

【讨论】:

【参考方案2】:

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

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

【讨论】:

以上是关于Rocket CORS 如何使用 Request Guard 返回字符串?的主要内容,如果未能解决你的问题,请参考以下文章

如何处理无效的 CORS 预检请求?

Rocket - regmapper - RegisterCrossing

CORS 发布请求失败

如何在生产中使用 Rocket 运行 Diesel 迁移?

Rust 的 Rocket Web 框架如何使用共享变量?

Cross-Origin Request Blocked:(原因:CORS 请求未成功)