引言
之前分享了 Tauri 初探,最近的一段时间使用 Tauri 在项目上实现了一些功能。遇到了一些坑,做个分享。
http 跨域问题
Tauri 实现的一般是一个 pc 的客户端程序,一般会有对服务端取数据的需求。可能这是一个局域网程序,所以也懒得部署 https 服务了。这时候 Tauri dev 下调试运行时正常的, 但是当你做完功能想编译成一个 exe 运行时,会发现网络请求失败了。
大致错误描述
The page at '<URL>' was loaded over HTTPS,
原因么就是 windows 上 Tauri 是基于 webview2 实现的,在安全性上有一些限制。目前该问题也没有得到完美的解决。不过经过研究,发现 Tauri 还是提供了一个方法,就是使用他提供的 http.fetch 接口来调用请求。然后发现控制台是无法查看到网络请求的。得出结论他是通过 Tauri 里面的 rust 去帮我们调用请求从而绕过了 webview2 前端框架。
所以 Tauri 里面的网络如果非 https 的话,就不能使用 axios 这个网络库了。而应该使用他提供的 http.fetch。
简单封装下
export enum RemoteUrl {
remoteA,
remoteB,
}
export const FetchGet = async (
remote: RemoteUrl,
path: string
): Promise<any> => {
const url = await (remote === RemoteUrl.remoteA ? remoteA() : remoteB());
return http.fetch(`${url}${path}`, { method: 'GET' });
};
export const FetchPost = async (
remote: RemoteUrl,
path: string,
body: any | null = null
): Promise<any> => {
const url = await (remote === RemoteUrl.remoteA ? remoteA() : remoteB());
return http.fetch(`${url}${path}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: body,
});
};
这里是存在多个服务端的情况
使用的代码
export const getSomething = (id: string) => {
return FetchGet(RemoteUrl.remoteA, `/getPath/${id}`);
};
export const postSomething = (data: {
name: string;
label: string[];
a: any[];
}): Promise<any> => {
return FetchPost(RemoteUrl.remoteB, '/postPath', {
type: 'Json',
payload: data,
});
};
ps:2023/6/13 fetch只能解决http的问题,但有时候我们还会用到websocket,这时候如果是局域网环境的app,可以试用localhost插件。 目前tauri官网提供了插件库,里面有localhost插件,支持http、ws, 这也是一个绕过安全墙的方式。
善用 event
Tauri 封装了个挺好用的 event。可以让你轻松的在 rust 代码和 H5 之间轻松的消息通信。
大致撸了个案例
fn main() {
let menu = Menu::new();
return tauri::Builder::default()
.menu(menu)
.setup(|app| {
// 持有apphandle的复制对象。然后可以对他为所欲为
let app_cp = app.handle();
// 在rust里面监听从h5发出来的消息
app.listen_global("new_window", |event| {
println!("{:?}", event);
});
// 建个线程,间隔5s朝外部广播消息
tauri::async_runtime::spawn(async move {
loop {
tokio::time::sleep(Duration::from_millis(5000)).await;
// 朝所有监听了haha事件的对象发消息
_ = app_cp.emit_all(
"haha",
TestData {
aa: "sss".to_string(),
bb: "ddd".to_string(),
},
);
_ = app_cp.emit_all("hehe", "sdsds");
// 单独对main window发送hehe事件
app_cp.emit_to("main", "hehe", "123123");
}
});
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
H5 实现
import { listen } from '@tauri-apps/api/event';
listen('haha', (event) => {
console.log('listen event', event);
});
结尾
暂时也没啥更多的分享,后续遇到大坑在补。
吐槽下Tauri的文档着实太少了。关于自定义安装配置的更是少之又少,还待探索。
国内貌似用Tauri的人很少,不知道有没有朋友有加群互帮互助的想法,在下摸鱼的方向比较多。最近在扩展rust技术栈,搞搞React,SwfitUI。
要加群的可以私信我