Actix Rust服务端无法响应浏览器CORS POST XHR/Fetch请求问题求助
问题修复方案
核心问题说明
- 前端错误配置了
mode: 'no-cors',该模式下浏览器会限制跨域请求的响应读取,且无法发送触发预检的复杂请求 - 后端未处理CORS预检OPTIONS请求:你发送的是Content-Type为application/json的POST请求,属于复杂跨域请求,浏览器会先发送OPTIONS方法的预检请求验证权限,你的后端仅实现了POST路由,预检直接失败
- 单接口手动添加CORS头不完整,无法覆盖预检请求场景
修复步骤
1. 调整前端fetch代码
删除mode: 'no-cors'配置,添加JSON格式对应的请求头:
fetch("http://127.0.0.1:8080/get", { method: 'POST', cache: 'no-cache', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ "t":"some data", "a":"an example", "c":0 }) });
2. 后端配置官方CORS中间件
首先在Cargo.toml中添加依赖:
actix-cors = "0.6"
修改后端主代码,挂载CORS中间件统一处理跨域逻辑,不需要再在单个接口手动加跨域头:
use actix_cors::Cors; use actix_web::{web, App, HttpResponse, HttpServer, Responder}; use serde::Deserialize; #[derive(Deserialize)] struct URL{ t : String, c : i32, a : String } #[post("/get")] async fn get_data(query: web::Json<URL>) -> impl Responder{ println!("Got a form data query"); HttpResponse::Ok().body(String::from("Success msg from server")) } #[actix_web::main] async fn main() -> std::io::Result<()> { HttpServer::new(|| { let cors = Cors::default() .allow_any_origin() .allow_any_method() .allow_any_header() .max_age(3600); App::new() .wrap(cors) .service(get_data) }) .bind("127.0.0.1:8080")? .run() .await }
额外说明
Postman测试正常是因为Postman不会执行浏览器的同源策略校验,也不会自动发送CORS预检请求,所以直接请求POST接口就能成功,和浏览器的运行逻辑有差异。
生产环境建议不要用allow_any_origin(),要指定具体允许的源,比如.allowed_origin("http://127.0.0.1:7500"),避免跨域权限过大带来安全问题。
内容的提问来源于stack exchange,提问作者Mathe Eliel
相关产品推荐
相关产品推荐

