前端跨域POST请求致actix-web服务失败的问题与解决
为什么前端发起跨域POST请求时,actix-web服务会失败?
问题相关代码
actix-web服务代码
use actix_web::{web, App, HttpServer, HttpResponse}; use serde::{Deserialize,Serialize}; #[actix_web::main] // or #[tokio::main] async fn main() -> std::io::Result<()> { let app = move || { App::new().configure(test_routes) }; HttpServer::new(app) .bind(("127.0.0.1", 7878))? .run() .await } pub fn test_routes(cfg: &mut web::ServiceConfig){ cfg .service( web::scope("/test") .route("/post",web::post().to(test_post)) .route("/get", web::get().to(test_get)) ); } pub async fn test_post(data: web::Json<MyRequest>) -> HttpResponse { println!( "{:?}", data.name ); HttpResponse::Ok().append_header(("Access-Control-Allow-Origin","*")).json("Hello,world") } pub async fn test_get() -> HttpResponse { HttpResponse::Ok().append_header(("Access-Control-Allow-Origin","*")).json("Hello,world") } #[derive(Serialize, Deserialize)] pub struct MyRequest { name: String, }
前端请求代码
/*POST*/ let xhr = new XMLHttpRequest() xhr.open("post","http://localhost:7878/test/post",true) xhr.setRequestHeader("Content-Type", "application/json") xhr.onload = function() { console.log("success") } let data = { name:"zack" } xhr.send(JSON.stringify(data)) /*GET*/ let xhr = new XMLHttpRequest() xhr.open("get","http://localhost:7878/test/get",true) xhr.onload = function() { console.log("success") } xhr.send()
报错信息
从源'null'访问XMLHttpRequest至'http://localhost:7878/test/post'已被CORS策略阻止:预检请求的响应未通过访问控制检查:请求的资源上不存在'Access-Control-Allow-Origin'头。
已尝试手动设置所有相关CORS头:Access-Control-Allow-Headers、Access-Control-Allow-Credentials、Access-Control-Allow-Methods、Access-Control-Allow-Origin、Access-Control-Expose-Headers,但问题仍未解决。
解决方法
通过使用actix-web的Cors中间件替代手动添加头的方式,问题得到解决。修改后的服务初始化代码如下:
App::new() .wrap( Cors::default() // 此处不能填*,否则会报错:Error: Custom { kind: Other, error: "can not start server service 0" } .allowed_origin("http://localhost:8080") .allowed_methods(vec!["GET", "POST"]) .allowed_headers(vec![http::header::AUTHORIZATION, http::header::ACCEPT, http::header::ACCESS_CONTROL_ALLOW_ORIGIN]) .allowed_header(http::header::CONTENT_TYPE) .max_age(3600) ).configure(test_routes)
内容的提问来源于stack exchange,提问作者coding-cuisine-bird
相关产品推荐
相关产品推荐

