在 Tauri 应用中,网络请求通常有两种实现路径:前端直接发起请求(通过 fetch 或 axios 等),或通过 Rust 后端发起请求(使用 Tauri 的 HTTP 插件或 reqwest 库)。后者更安全、更可控,尤其适合需要额外处理(如设置自定义证书、代理、请求拦截)的场景。下面以 Tauri v2 推荐的 @tauri-apps/plugin-http 为例,说明 GET/POST 请求的配置与响应处理。
1. 启用 HTTP 插件
首先安装插件,并在 tauri.conf.json 中声明权限。
{
"plugins": {
"http": {
"scope": ["https://api.example.com/*"]
}
}
}
上面的 scope 采用白名单机制,只有匹配该模式的 URL 才允许访问,其他请求会被自动拦截。这能有效防止恶意前端代码向任意地址发送请求。
2. GET 请求
在前端 JavaScript/TypeScript 中:
import { fetch } from '@tauri-apps/plugin-http';
const response = await fetch('https://api.example.com/data', {
method: 'GET',
headers: {
'Accept': 'application/json',
},
});
if (response.ok) {
const data = await response.json();
console.log(data);
} else {
console.error('请求失败', response.status);
}
注意这里用的是 Tauri 提供的 fetch,它底层会委托给 Rust 的 HTTP 客户端,而不是浏览器自带的 fetch。这就保证了请求不受浏览器同源策略的限制(因为是在原生层发出的),同时也能在请求头中添加一些浏览器无法自定义的字段(如自定义 User-Agent)。
3. POST 请求
发送 JSON 数据:
const response = await fetch('https://api.example.com/submit', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ name: 'Tauri', version: 2 }),
});
const result = await response.text();
如果需要发送表单数据(application/x-www-form-urlencoded 或 multipart/form-data),可以直接构造 URLSearchParams 或 FormData 对象作为 body,用法与标准 API 一致。
4. 请求配置
fetch 支持大部分标准选项,此外 Tauri 还扩展了一些实用的配置能力:
- 超时时间:通过
AbortController或插件的connectTimeout(在 Rust 端配置)来实现。推荐在 Rust 的tauri.conf.json中全局设置:
"plugins": {
"http": {
"connectTimeout": 10000, // 10 秒
"readTimeout": 15000
}
}
- 自定义证书:插件支持忽略 HTTPS 证书错误(仅限开发)或指定自定义 CA 证书。例如在
Cargo.toml中启用native-tls或rustls,然后在初始化插件时传入证书路径。
- 代理设置:可以读取系统代理,也可以手动指定
socks5://...或http://...代理地址。
- 请求拦截器:如果需要统一添加认证 Token 或日志,可以封装一个自定义的
request函数,而不是直接使用fetch。这样可以避免在每个请求里重复写 header。
async function apiFetch(url, options = {}) {
const token = await getAuthToken(); // 从某处获取 token
const headers = {
...options.headers,
'Authorization': `Bearer ${token}`,
};
return fetch(url, { ...options, headers });
}
5. 响应处理
Tauri 的 fetch 返回的 Response 对象具有以下常用方法:
response.json()—— 解析 JSON 响应体response.text()—— 读取纯文本response.arrayBuffer()—— 获取二进制数据(适合下载文件)response.blob()—— 获取 Blob(与 Web API 兼容)response.status和response.statusText—— 状态码和描述response.headers—— 响应头(Headers对象)
一个健壮的响应处理流程应该同时处理成功数据与错误情况:
try {
const response = await fetch(url);
if (!response.ok) {
// 业务错误:4xx、5xx
const errorBody = await response.text();
throw new Error(`服务器错误 ${response.status}: ${errorBody}`);
}
const data = await response.json();
return data;
} catch (err) {
if (err.name === 'AbortError') {
// 请求被取消
console.warn('请求已超时或手动取消');
} else if (err.message.includes('Failed to fetch')) {
// 网络不通或域名解析失败
console.error('网络连接失败,请检查网络');
} else {
console.error('请求异常', err);
}
throw err; // 或者返回一个友好的错误对象
}
6. 纯 Rust 端请求(适合后端逻辑)
如果某些请求必须在 Rust 里完成(例如需要持久化处理、后台任务),可以使用 reqwest 库。在 Tauri 命令中调用:
#[tauri::command]
async fn fetch_data(url: String) -> Result<String, String> {
let client = reqwest::Client::new();
let resp = client.get(&url)
.timeout(std::time::Duration::from_secs(10))
.send()
.await
.map_err(|e| e.to_string())?;
let body = resp.text().await.map_err(|e| e.to_string())?;
Ok(body)
}
这种方式完全绕开了前端,适合处理机密数据或需要稳定运行的后台同步任务。
关键点总结
- 通过
@tauri-apps/plugin-http获得一个安全的、不受浏览器限制的fetch实现。 - 必须在
tauri.conf.json的scope中显式授权目标 URL,否则请求会被拦截。 - 请求配置支持超时、自定义证书和代理,可以在配置文件中全局设定。
- 响应处理要覆盖网络异常、业务错误和超时,确保用户体验顺畅。
- 如果需要在后台静默执行 HTTP 调用,直接用 Rust 的
reqwest更高效且可靠。