axum框架发现无法通过cors跨域规则, 禁止了options prefilght请求

字号+ 编辑: 国内TP粉 修订: 种花家 来源: 原创 2023-09-18 我要说两句(0)

辛辛苦苦用axum写了一堆东西, 结果发现线上根本没办法实现跨域?

写了半天在本地跑的好好的, 结果上不了线可就糗大了。

笔者刚开始使用的是nginx在配置文件里填写了http响应header的, 发现在ajax请求场景下不好控制。打算用tower_http库的的CorsLayer来解决跨域灵活性的问题, 以下是代码:

use axum::{routing::{get}, Router};
use axum::http::Method;
use sqlx::{MySql, Pool};
use tower_http::cors::{CorsLayer, Any};

pub fn app(pool: Pool<MySql>) -> Router {
    let cors1 = CorsLayer::new()
        .allow_methods([Method::GET, Method::POST, Method::OPTIONS])
        // 允许一切来源
        .allow_origin(Any)
        .allow_headers(Any);

    Router::new()
        .route("/", get(index_controller::handler)) // 首页
        .route("/list_name_avatar", get(some_controller::list_some)) // 某个控制下的方法
        .layer(cors1)
        .with_state(pool)
}


上述代码中, 笔者用到了mysql链接池, 会有pool出现, 这一段可以先不看。重点看配置cors规则时的操作, 首先

allow_methods allow_origin allow_headers是我们常用到的三个方法,分别限定了请求类型、请求站点、请求头。不想细写只求跑通就按照我这么写。

接下来layer()方法里面传入cors1配置。layer的出现顺序是有讲究的, 因为Router后面的方法是一层一层包装和返回的, layer()方法的每次调用只影响它上层的route(), 而不管他下面(外面层)的路由方法。

常见问题总结

笔者用上述玩法是可以跑通的,那为什么会遇到405的错误呢?

首先看ajax传输请求方式是什么?

如果你检查ajax的代码, 以jquery封装的$.ajax为例, 通常type字段只有get和post两种, 例如:

$.ajax({

    type: "GET",

    // TODO

})

但上述代码浏览器跑起来一看, 会看到它会尝试options和GET两次, 实际你只要管GET就行了。如果你在axum的路由里配置的是post, 但ajax请求的类型配置成get, 那无论nginx配置文件怎么搞都会出现405。另外js的console会报错: Access-allow-origin或者某其他跨域配置字段只允许出现一次xxx。这些都会使人迷惑。

跨域到底是哪里引发的报错?

这个问题是老生常谈了。笔者总结,报错的原因主要是:

1、客户端的请求方式和跨域对应的允许范围不匹配。

2、服务端方面,要么是nginx配置文件, 要么是后端(rust路由)的跨域配置出现了问题; 建议nginx配置了跨域, 后端流程能跑通就别动, 否则就撤掉nginx的跨域配置只配置后端。

网上有的说要在ajax的请求头里加上xxx, 能解决问题?笔者倒是没碰过, 估计是想多了,服务端默认不让跨域,客户端难道能擅自做主?

跨域报错的话, axum内部的业务逻辑方法会执行吗?

有的情况下会考虑到是不是业务逻辑影响的。实测请求会被拦截, 不存在内部业务逻辑引起的跨域问题。如果跨域配置对了,内部业务逻辑没跑通,只会报业务逻辑的bug;

阅完此文,您的感想如何?
  • 有用

    139

  • 没用

    7

  • 开心

    16

  • 愤怒

    8

  • 可怜

    19

1.如文章侵犯了您的版权,请发邮件通知本站,该文章将在24小时内删除;
2.本站标注原创的文章,转发时烦请注明来源;
3.交流群: PHP+JS聊天群

相关课文
  • 在rust/axum框架中操作redis

  • rust编译新的wasm项目操作流程(原文: 编译 Rust 为 WebAssembly)

  • rust视图模板库askama的使用

  • axum框架当中获取请求header, 和获取header指定字段的方法

我要说说
网上宾友点评