rust 为什么我的actix-web在前端跨域发布时失败?

xpcnnkqh  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(237)

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 js代码

/*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()


前端错误消息如下:
CORS策略已阻止从源“null”访问位于“http://localhost:7878/test/post”的XMLHttpRequest:对预处理请求的响应未通过访问控制检查:请求的资源上不存在“PACK-Control-Allow-Origin”标头。
我已经尝试了所有的控制允许头、控制允许凭证、控制允许方法、控制允许源、控制暴露头enter image description here
谢谢@richzilla的帮助,这个问题已经解决了,这是改变代码

App::new()
            .wrap(
                Cors::default()
                    // here is cannot fill out *, or else 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)

sycxhyv7

sycxhyv71#

当您的浏览器向您的端点发出请求时,它将在向/post发送POST请求之前发送一个“pre-flight”CORS请求。此pre-flight请求是通过OPTIONS方法发送的。
由于您已将CORS标头配置为对POST请求的响应,因此您的浏览器永远不会看到它们。
如果在发出请求时打开浏览器开发工具,您可以看到这种行为。
为了确保您的浏览器可以读取您的CORS头,您需要在/post上有一个路由,它需要一个OPTIONS请求,这将返回您的CORS头。
与手动执行此操作相比,使用库来处理此逻辑更容易,对于Actix Web,有以下库:https://docs.rs/actix-cors/latest/actix_cors/#

相关问题