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", "*")); } }
关键说明
- 修改Fairing的Kind:将
Kind::Response改为Kind::Request | Kind::Response,让Fairing能在请求到达路由匹配前拦截OPTIONS请求。 - 处理OPTIONS请求:在
on_request方法中识别OPTIONS请求,直接构造200响应并注入CORS头,同时标记请求数据为已完成,跳过后续路由匹配流程。 - 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
相关产品推荐
相关产品推荐

