即使使用 CorsLayer,Axum 路由器也拒绝使用 405 进行 CORS 选项预检

Ali*_*Lee 4 cors http-status-code-405 rust rust-tower rust-axum

fetch在发送a 之前,浏览器将发送一个请求方法OPTIONS来确认 API 将接受来自特定来源的脚本的请求。

\n

Chrome 显示我的 Axum 服务器正在拒绝我客户端的 405 请求。我的路由器如下所示:

\n
let app = Router::new()\n    .layer(TraceLayer::new_for_http())\n    .layer(CorsLayer::permissive())\n    .route("/api", post(server));\n
Run Code Online (Sandbox Code Playgroud)\n

Router::layer表示所有到router的请求都会被layer\xe2\x80\x99s对应的中间件处理。但我不确定它是否发挥了作用。

\n

Ali*_*Lee 10

.layer()函数是一个构建器,因此返回一个 new Router,其中包含内部路由器。该路由/api将首先被测试并被拒绝 405,因为仅POST支持请求方法 - 不支持OPTIONS

总之,您需要CorsLayer“外部”路线,以便它可以响应OPTIONS请求。

请注意文档中的示例:

// All requests to `first_handler` and `second_handler` will be sent through
// `ConcurrencyLimit`
let app = Router::new().route("/", get(first_handler))
    .route("/foo", get(second_handler))
    .layer(ConcurrencyLimitLayer::new(64))
    // Request to `GET /bar` will go directly to `third_handler` and
    // wont be sent through `ConcurrencyLimit`
    .route("/bar", get(third_handler));
Run Code Online (Sandbox Code Playgroud)

顺便说一下,TraceLayer出于同样的原因,您没有跟踪您的 API 调用!

试试这个,你会看到OPTIONS记录的请求,并且POST应该命中你的server

let app = Router::new()
    .route("/api", post(server))
    .layer(CorsLayer::permissive())
    .layer(TraceLayer::new_for_http());
Run Code Online (Sandbox Code Playgroud)