You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rocket.rs 0.5-rc.3 CORS配置失效,OPTIONS请求无匹配路由求助

解决Rocket.rs 0.5-rc.3的CORS配置问题

你遇到的核心问题是:OPTIONS预检请求没有匹配到对应路由,直接返回404,而你的自定义Fairing仅在响应阶段生效,根本没机会处理OPTIONS请求的响应。

修复方案

修改CORS Fairing,同时处理请求和响应阶段:在请求阶段拦截OPTIONS请求,直接返回带CORS头的200响应;在响应阶段给正常请求的响应添加CORS头。

完整代码示例

use rocket::{Request, Response, Data, Fairing, Info, Kind, http::{Method, Status, Header}};

pub struct CORS;

#[rocket::async_trait]
impl Fairing for CORS {
    fn info(&self) -> Info {
        Info {
            name: "CORS Handler",
            kind: Kind::Request | Kind::Response,
        }
    }

    // 拦截OPTIONS预检请求,直接返回响应
    async fn on_request<'r>(&self, request: &'r mut Request<'_>, data: &mut Data<'r>) {
        if request.method() == Method::Options {
            let mut response = Response::new();
            response.set_status(Status::Ok);
            self.inject_cors_headers(request, &mut response);
            request.set_response(response);
            data.set_complete();
        }
    }

    // 给常规请求的响应添加CORS头
    async fn on_response<'r>(&self, request: &'r Request<'_>, response: &mut Response<'r>) {
        self.inject_cors_headers(request, response);
    }

    // 提取公共的CORS头注入逻辑
    fn inject_cors_headers(&self, request: &Request<'_>, response: &mut Response<'_>) {
        // 处理带Credentials的场景:动态匹配请求Origin,而非固定为*
        match request.headers().get_one("Origin") {
            Some(origin) => {
                response.set_header(Header::new("Access-Control-Allow-Origin", origin));
                response.set_header(Header::new("Access-Control-Allow-Credentials", "true"));
            }
            None => {
                response.set_header(Header::new("Access-Control-Allow-Origin", "*"));
            }
        }

        response.set_header(Header::new("Access-Control-Allow-Methods", "POST, GET, PATCH, OPTIONS"));
        response.set_header(Header::new("Access-Control-Allow-Headers", "*"));
    }
}

关键说明

  1. 修改Fairing的Kind:将Kind::Response改为Kind::Request | Kind::Response,让Fairing能在请求到达路由匹配前拦截OPTIONS请求。
  2. 处理OPTIONS请求:在on_request方法中识别OPTIONS请求,直接构造200响应并注入CORS头,同时标记请求数据为已完成,跳过后续路由匹配流程。
  3. Credentials兼容性:如果前端需要发送带Cookie的请求,不能将Access-Control-Allow-Origin设为*,必须动态匹配请求的Origin头,同时保留Access-Control-Allow-Credentials: true。如果不需要Credentials,可以简化为固定*。

挂载Fairing

主函数的挂载代码无需修改,保持原有的attach(CORS)即可:

fn main(){
    let state = // 你的状态初始化逻辑
    let _rocket = rocket::build()
        .manage(state)
        .attach(CORS)
        // 其他路由挂载逻辑
        .launch()
        .await
        .expect("Rocket launch failed");
}

内容的提问来源于stack exchange,提问作者Rick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 12:24:59