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.交流群: 2702237 13835667

相關課文
  • 在rust/axum框架中操作redis

  • rust編譯新的wasm項目操作流程(原文: 編譯 Rust 爲 WebAssembly)

  • rust視圖模板庫askama的使用

  • axum框架當中獲取請求header, 和獲取header指定字段的方法

我要說說
網上賓友點評