You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React调用Actix API遇CORS错误:缺少Access-Control-Allow-Origin头

React调用Actix API时的CORS错误解决

问题描述

React调用Actix API时触发CORS错误,提示请求资源不存在Access-Control-Allow-Origin头。移除请求中的Authorization头后API可正常响应,手动在Actix返回中添加该头也无效。

完整错误信息:

Access to fetch at 'https://exampleip/richieste' from origin 'https://exampleip' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

相关代码

React请求代码

async function richiesteFn() {
  try {
    const response = await fetch('https://exampleip/richieste', {
      method: 'GET',
      headers: {
        Authorization: sessionStorage.getItem('auth0_token'),
      },
    });
    const data = await response.json();
    // console.log(data);
    return data;
  } catch (error) {
    return error;
  }
}

Actix API接口代码

#[get("/richieste")]
async fn richieste_srvc(req: HttpRequest) -> HttpResponse {
    let authorization_present = req.headers().contains_key("Authorization");
    if authorization_present {
        let authorization = req.headers().get("Authorization").unwrap();
        let auth_str = authorization.to_str().unwrap();
        let validate_token_fn = validate_auth0_token(&auth_str);
        if validate_token_fn.is_err(){ 
            let error = validate_token_fn.unwrap_err();
            let err_str = format!("{{ \"Error\": \"{}\" }}", error);
            HttpResponse::Ok().body(err_str)
        } else {
            let str = mostra_richieste();
            if str.is_err() {
                let error = str.unwrap_err();
                let err_str = format!("{{ \"Error\": \"Errore nella lista richieste: {}\" }}", error);
                HttpResponse::Ok().content_type(ContentType::json()).body(err_str)
            } else {
                HttpResponse::Ok().content_type(ContentType::json()).body(str.unwrap())
            }
        }
    } else {
        let err_str = format!("{{ \"Error\": \"Authorization header not present\" }}");
        HttpResponse::Ok().content_type(ContentType::json()).body(err_str)
    }
}

Actix服务启动代码

HttpServer::new(move || {
        let logger = Logger::default();
        let cors_allowed_origin = env::var("CORS_ALLOWED_ORIGIN").unwrap();
        let cors = Cors::default()
        .allowed_origin(&cors_allowed_origin);
        App::new()
            .wrap(logger)
            .wrap(cors)
            .service(login)
            .service(validate_token)
            .service(richieste_srvc)
    })

解决方案

问题核心是预检请求(OPTIONS)未被正确处理:当请求包含Authorization这类非简单头时,浏览器会先发送OPTIONS预检请求验证权限,你的CORS配置未允许自定义头和OPTIONS方法,导致预检失败。

  1. 更新CORS配置,允许自定义头与预检方法
    修改Actix启动代码中的CORS配置,添加对Authorization头和OPTIONS方法的支持:

    let cors = Cors::default()
        .allowed_origin(&cors_allowed_origin)
        .allowed_header("Authorization") // 显式允许Authorization头
        .allowed_methods(vec!["GET", "OPTIONS"]) // 允许请求方法,包含预检用的OPTIONS
        .supports_credentials(); // 若请求需要携带凭证(如cookie),保留此行,否则可移除
    
  2. 调整中间件顺序
    确保CORS中间件优先于Logger执行,因为预检请求需要先被CORS中间件处理:

    App::new()
        .wrap(cors) // 先加载CORS中间件
        .wrap(logger)
        .service(login)
        .service(validate_token)
        .service(richieste_srvc)
    
  3. 校验环境变量值
    确认CORS_ALLOWED_ORIGIN环境变量的值与React应用的Origin完全一致,不要带末尾斜杠(如正确值为https://exampleip,而非https://exampleip/)。

  4. 禁止手动添加CORS头
    不要在接口的HttpResponse中手动添加Access-Control-Allow-Origin头,Actix的CORS中间件会自动处理,手动添加可能导致头冲突。


内容的提问来源于stack exchange,提问作者GranBoh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 16:02:50