用tauri實現標準的http請求,代替原來的ajax請求,解決跨域問題

字號+ 編輯: 种花家 修訂: 种花家 來源: 原创 2024-07-30 我要說兩句(0)

如果在tauri裡内嵌fetch或者axois,會發現調試器返回Access-Control-Allow-Origin cannot contain more than one origin, 這就很難受了,文本介紹遇到這種跨域問題的解決方法。

如本文题中描述,实际产品中,客户端很大几率是要通过rust内封装好的http的reqwest包,请求远程服务器的内容,类似于web的ajax请求。如果你用fetch或者axios这些库,会遇到类似

Access-Control-Allow-Origin cannot contain more than one origin

这种涉及到跨域错误的问题。如果你不想碰rust的reqwest,最简单的土办法是使用jquery的XHR封装好的$.ajax,当然别忘了在headers里面传输一个字段:

"X-Requested-With":"XMLHttpRequest"

来模拟普通的web ajax请求,可以规避问题,同时适应后端接口的检查。

但在tauri官方看来,这种实现是“不正常”的。他们希望你invoke到rust后端的handler请求列表的方法名,通过rust客户端模块去做统一请求和返回。从代码层面上,这是怎么实现的呢?

代码实现

tauri的基本项目代码,你按照官方给的demo就可以做到。本文只说tauri“标准”设计上http请求有关的变动,我们先看main.rs里的tauri的启动代码

tauri::Builder::default()
    .invoke_handler(tauri::generate_handler![
        close_splashscreen,
        class_file1::fn_foo,
        class_file1::fn_bar,
        class_file2::fn_alpha,
    ])
    .menu(menu)
    .on_menu_event(|event| {
        match event.menu_item_id() {
            "quit" => {
                std::process::exit(0);
            }
            "close" => {
                event.window().close().unwrap();
            }
            _ => {}
        }
    })
    .run(tauri::generate_context!())
    .expect("Program crashed.");

关注一下上述代码当中的tauri::generate_handler!巨集,有若干方法,绑定的是rust项目里面的class_file1文件下的公开方法fn_foo方法等等。于是,新建一个class_file1.rs, 然后在main.rs里添加mod关联:

mod class_file1;

fn_foo.rs的内部实现一个请求方法:

#[tauri::command]
pub async fn fn_foo(some_arg: u32) -> String {
    match reqwest::get(format!("https://api.wwooo.com/some_url?arg1={}", some_arg))
        .await {
        Ok(resp) => resp.text().await.unwrap(),
        Err(err) => format!("{}", err)
    }
}

其中上述代码中的api.wwooo.com/some_url?arg1=xxx就是你实际的后端接口地址。返回结果写String? 因为接口返回返回结果变量resp确实也都是一些json字符串。

注意,这里的some_arg的检查是严格的,你如果怕程序报错,可以按需在业务逻辑里分配一些默认的参数。

接下来,前端页面javascript代码里,要invoke关键字和一下rust代码中的方法名一致。实际生产中,我会先封装一个异步的js方法,比如:

async function get_my_data(arg1) {
    let r = await invoke("fn_foo", {arg1: Number(arg1)});

    r = JSON.parse(r);

    if (typeof r.code != 'undefined' && r.code === 1) {
        // TODO
        // 我的后端会返回{"code": XXX, "xxx": XXX... } 这样的json串
        // 你的业务逻辑
    }
    
    // 补充其他的业务逻辑
}

这样,你在适当的场景下调用这个函数就可以和普通的axois/ajax请求一样操作了

有的时候需要先把这个async方法的代码封装到稍微靠前面一点,笔者用的是比较早版本的tauri, JS会报一些奇怪的加载顺序错误,找不到方法。

有些人实在懒得分那么多文件,那可以把所有的handler函数都写到main.rs一个文件里,这也没有问题。

接下来用

cargo tauri dev

测试一下,看看跑通没?

总结

网上有一些说tauri完败或者完胜electron.js的论调。从实际开发我们看,tauri有rust的加持后,甩开了node.js沉重的包袱,有不少可取之处。可以应用于生产。

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

    1

  • 沒用

    0

  • 開心

    0

  • 憤怒

    0

  • 可憐

    0

1.如文章侵犯了您的版權,請發郵件通知本站,該文章將在24小時内刪除;
2.本站標注原創的文章,轉發時煩請注明來源;
3.交流群: 2702237 13835667

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

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

  • rust視圖模板庫askama的使用

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

我要說說
網上賓友點評