Wil*_*ill 3 http rust dart rust-rocket flutter-web
我有一个运行 Rocket.rs 的后端,我的 Flutter Web 应用程序向它发送请求,但它无法通过 OPTIONS 响应。
我曾尝试将 CORS (rocket_cors) 添加到后端并有一个选项响应,但它仍然发回:
Error: XMLHttpRequest error.
dart:sdk_internal 124039:30 get current
packages/http/src/browser_client.dart.lib.js 214:124 <fn>
Run Code Online (Sandbox Code Playgroud)
我在我的火箭项目中添加了以下内容:
Error: XMLHttpRequest error.
dart:sdk_internal 124039:30 get current
packages/http/src/browser_client.dart.lib.js 214:124 <fn>
Run Code Online (Sandbox Code Playgroud)
我的颤振应用程序正在运行此请求:
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;
}
Run Code Online (Sandbox Code Playgroud)
问题:这是响应 OPTION 请求的正确方法,如果不是,我如何在 Rocket.rs 中实现它?
mig*_*hen 15
这对我来说适用于 Rocket 0.5.0-rc.2,没有其他依赖项。它基于上面的答案和一些互联网搜索。
use rocket::fairing::{Fairing, Info, Kind};
use rocket::http::Header;
use rocket::log::private::debug;
use rocket::serde::json::Json;
use rocket::{Request, Response};
#[macro_use]
extern crate rocket;
#[launch]
fn rocket() -> _ {
rocket::build()
.attach(Cors)
.mount("/", routes![index, all_options, insert])
}
/// Some getter
#[get("/")]
fn index() -> &'static str {
"Hello CORS"
}
/// Some setter
#[post("/", data = "<data>")]
async fn insert(data: Json<Vec<String>>) {
debug!("Received data");
}
/// Catches all OPTION requests in order to get the CORS related Fairing triggered.
#[options("/<_..>")]
fn all_options() {
/* Intentionally left empty */
}
pub struct Cors;
#[rocket::async_trait]
impl Fairing for Cors {
fn info(&self) -> Info {
Info {
name: "Cross-Origin-Resource-Sharing Fairing",
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, PATCH, PUT, DELETE, HEAD, OPTIONS, GET",
));
response.set_header(Header::new("Access-Control-Allow-Headers", "*"));
response.set_header(Header::new("Access-Control-Allow-Credentials", "true"));
}
}
Run Code Online (Sandbox Code Playgroud)
为了让服务器提供外部 API,它需要能够处理跨域资源共享 (CORS)。CORS 是一种基于 HTTP 标头的机制,它允许服务器指示浏览器应允许加载资源的来源(域、协议或端口)。
您可以创建一个整流罩来为您的应用程序全局处理 CORS。一个非常宽松的版本如下,但当然,您必须根据您的特定应用程序进行定制:
use rocket::http::Header;
use rocket::{Request, Response};
use rocket::fairing::{Fairing, Info, Kind};
pub struct CORS;
impl Fairing for CORS {
fn info(&self) -> Info {
Info {
name: "Add CORS headers to responses",
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"));
}
}
Run Code Online (Sandbox Code Playgroud)
你只需要像这样连接整流罩:
rocket::ignite().attach(CORS)
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用rocket_cors
板条箱。
use rocket::http::Method;
use rocket_cors::{AllowedOrigins, CorsOptions};
let cors = CorsOptions::default()
.allowed_origins(AllowedOrigins::all())
.allowed_methods(
vec![Method::Get, Method::Post, Method::Patch]
.into_iter()
.map(From::from)
.collect(),
)
.allow_credentials(true);
rocket::ignite().attach(cors.to_cors().unwrap())
Run Code Online (Sandbox Code Playgroud)
您可以在此处了解有关 CORS 和访问控制标头的更多信息
这对我来说很有效:
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: "Attaching 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"));
}
}
Run Code Online (Sandbox Code Playgroud)
并且您必须使用启动宏将其附加到函数中:
#[launch]
fn rocket() -> _ {
rocket::build()
.attach(CORS)
.mount("/index", routes![index])
}
Run Code Online (Sandbox Code Playgroud)