CORS blocking only POST method #2510
-
I have implemented my own Fairing trait for CORS and it is allowing use rocket::http::Header;
use rocket::{Request, Response};
use rocket::fairing::{Fairing, Info, Kind};
pub struct CORS;
#[rocket::async_trait]
impl Fairing for CORS {
fn info(&self) -> Info {
Info {
name: "Add CORS headers to responses",
kind: Kind::Response
}
}
async fn on_response<'r>(&self, _request: &'r Request<'_>, response: &mut Response<'r>) {
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", "*"));
response.set_header(Header::new("Access-Control-Allow-Credentials", "true"));
}
} |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Since the browser does a CORS preflight request with a HTTP OPTIONS method (Read more here: https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request). You need to handle that accordingly. #[macro_use]
extern crate rocket;
use rocket::fairing::{Fairing, Info, Kind};
use rocket::http::{Header, self, Status};
use rocket::response::content;
use rocket::{Request, Response};
pub struct CORS;
#[rocket::async_trait]
impl Fairing for CORS {
fn info(&self) -> Info {
Info {
name: "Add CORS headers to responses",
kind: Kind::Response,
}
}
async fn on_response<'r>(&self, request: &'r Request<'_>, response: &mut Response<'r>) {
response.set_header(Header::new("Access-Control-Allow-Origin", "*"));
response.set_header(Header::new(
"Access-Control-Allow-Methods",
"POST, GET, HEAD, PATCH, OPTIONS",
));
response.set_header(Header::new("Access-Control-Allow-Headers", "*"));
response.set_header(Header::new("Access-Control-Allow-Credentials", "true"));
if request.method() == http::Method::Options && request.route().is_none() {
response.set_status(Status::NoContent);
let _ = response.body_mut().take();
}
}
}
#[get("/")]
fn index() -> content::RawJson<&'static str> {
content::RawJson("{ \"hi\": \"world\" }")
}
#[post("/cors")]
fn cors_test() -> content::RawJson<&'static str> {
content::RawJson("{ \"hi\": \"post\" }")
}
#[launch]
fn rocket() -> _ {
rocket::build()
.attach(CORS)
.mount("/", routes![index, cors_test])
} The open source rocket_cors package, does somthing similar: https://github.com/lawliet89/rocket_cors/blob/master/src/fairing.rs#L84 That sould fix your problem. Let me know if it still doesn't work. Another way would also be to define a options route that handles all OPTIONS requests: /// Catches all OPTION requests in order to get the CORS related Fairing triggered.
#[options("/<_..>")]
fn all_options() -> status::NoContent {
status::NoContent
} But i think doing it in the middleware is a little nicer :-) |
Beta Was this translation helpful? Give feedback.
Since the browser does a CORS preflight request with a HTTP OPTIONS method (Read more here: https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request). You need to handle that accordingly.