问题
I've got a backend running rocket.rs which my flutter web app sends a request to, but it can't get past the OPTIONS response.
I have tried adding CORS (rocket_cors) to the backend and having a options response, but it still sends back:
Error: XMLHttpRequest error.
dart:sdk_internal 124039:30 get current
packages/http/src/browser_client.dart.lib.js 214:124 <fn>
I have added the following to my rocket project:
#[options("/")]
fn send_options<'a>(path: PathBuf) -> Response<'a> {
let mut res = Response::new();
res.set_status(Status::new(200, "No Content"));
res.adjoin_header(ContentType::Plain);
res.adjoin_raw_header("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
res.adjoin_raw_header("Access-Control-Allow-Origin", "*");
res.adjoin_raw_header("Access-Control-Allow-Credentials", "true");
res.adjoin_raw_header("Access-Control-Allow-Headers", "Content-Type");
res
And my flutter app is running this request:
Future<String> fetchData() async {
final data2 = await http.get("http://my-web-site.com").then((response) { // doesn't get past here
return response.body;
});
return data2;
}
Question: Is this the proper way to respond to OPTION requests, and if not, how can I implement it in rocket.rs?
回答1:
In order for a server to provide an external API it needs to be able to deal with Cross Origin Resource Sharing (CORS). CORS is an HTTP-header based mechanism that allows a server to indicate which origins (domain, protocol, or port) that a browser should permit loading of resources.
You can create a fairing to handle CORS globally for your app. For example, the following will allow GET
, POST
, PATCH
, or OPTIONS
requests from any origin:
use rocket::{Request, Response};
use rocket::fairing::{Fairing, Info, Kind};
use rocket::http::Header;
pub struct CORS();
impl Fairing for CORS {
fn info(&self) -> Info {
Info {
name: "Add CORS headers to requests",
kind: Kind::Response
}
}
fn on_response(&self, request: &Request, response: &mut Response) {
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"));
}
}
You just have to attach the fairing like this:
rocket::ignite().attach(CORS())
You can learn more about CORS Response headers here
回答2:
Lambda Fairy's comment answered it for me.
I put it all in the GET
Handler:
#[get("/")]
fn get_handler<'a>() -> Response<'a> {
let mut res = Response::new();
res.set_status(Status::new(200, "No Content"));
res.adjoin_header(ContentType::Plain);
res.adjoin_raw_header("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
res.adjoin_raw_header("Access-Control-Allow-Origin", "*");
res.adjoin_raw_header("Access-Control-Allow-Credentials", "true");
res.adjoin_raw_header("Access-Control-Allow-Headers", "Content-Type");
res.set_sized_body(Cursor::new("Response"));
res
来源:https://stackoverflow.com/questions/62412361/how-to-set-up-cors-or-options-for-rocket-rs