HTTP 请求
本教程共 48 篇 · 第 34 篇 · 更新于 2026-08-09 · 约 8 分钟阅读
本节目标:读完你能用 plugin-http 在前端 JS 和 Rust 端发起 HTTP 请求,配置 URL 白名单授权,并理解它和浏览器原生 fetch 的区别。
桌面应用经常需要和后端 API 通信——拉数据、提交表单、下载文件。浏览器的 fetch API 不错,但它有跨域(CORS)限制,而且某些请求头被浏览器禁用。Tauri 的 tauri-plugin-http(HTTP 插件)把请求转发到 Rust 端执行,绕过了浏览器的 CORS 限制,同时提供了 URL 白名单机制来控制「前端能请求哪些地址」,保证安全。
安装与注册 http 插件
照例两端都装:
# 1. Rust 端添加依赖
cd src-tauri
cargo add tauri-plugin-http
// 2. 在 Builder 中注册插件
// src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_http::init())
.run(tauri::generate_context!())
.expect("运行 Tauri 应用时出错");
}
# 3. 前端安装 JS 包
npm install @tauri-apps/plugin-http
装好后,前端就能从 @tauri-apps/plugin-http 导入 fetch 函数来发请求了。
URL 白名单:控制能请求哪些地址
和 Shell 插件类似,HTTP 插件默认拒绝所有请求。你必须在 capability 里声明允许访问的 URL。这是安全核心——不能让前端随意请求任意服务器。
在 src-tauri/capabilities/default.json 里配置:
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "main-capability",
"description": "主窗口权限",
"windows": ["main"],
"permissions": [
{
"identifier": "http:default",
"allow": [{ "url": "https://*.tauri.app" }],
"deny": [{ "url": "https://private.tauri.app" }]
}
]
}
allow: 允许请求的 URL 列表,支持通配符*。https://*.tauri.app表示允许请求api.tauri.app、test.tauri.app等子域名。deny: 显式拒绝的 URL,优先级高于allow。即使某个 URL 匹配了 allow 的通配符,只要也匹配 deny,就会被拦住。
Tip通配符
*只匹配单级域名。https://*.tauri.app匹配api.tauri.app但不匹配v2.api.tauri.app。如果要匹配多级子域名,写https://**.tauri.app。具体行为以实际测试为准。
前端 JS:fetch 发请求
HTTP 插件的 fetch 方法刻意做得和浏览器的 Fetch API 几乎一样,降低了学习成本:
import { fetch } from "@tauri-apps/plugin-http";
// 发送 GET 请求
const response = await fetch("https://api.tauri.app/data.json", {
method: "GET",
});
console.log(response.status); // 200
console.log(response.statusText); // OK
// 读取响应体(JSON)
const data = await response.json();
console.log(data);
发 POST 请求也和浏览器 fetch 一模一样:
const response = await fetch("https://api.tauri.app/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
username: "admin",
password: "123456",
}),
});
const result = await response.json();
fetch 返回的 Response 对象支持 .text()、.json()、.arrayBuffer()、.blob() 等方法,和浏览器原生 fetch 用法一致。你可以像写普通前端网络请求一样用它。
Note虽然 API 长得像浏览器 fetch,但底层实现完全不同——请求是通过 Rust 端发出的,不经过浏览器的网络栈。这意味着没有 CORS 预检(preflight)请求,也不会被浏览器的安全策略拦截。但 Tauri 用自己的 URL 白名单机制替代了 CORS,安全控制权在你手里。
被禁用的请求头
为了安全,HTTP 插件默认会忽略一些「禁止的请求头(forbidden headers)」——这些是 Fetch 规范 中定义的浏览器不允许 JS 设置的头,比如 Host、Origin、Content-Length 等。
如果你确实需要设置这些头(比如和某些后端通信时),可以在 Cargo.toml 里开启 unsafe-headers 特性:
[dependencies]
tauri-plugin-http = { version = "2", features = ["unsafe-headers"] }
开启后,插件不再过滤任何请求头,前端可以自由设置所有 header。
Warning
unsafe-headers顾名思义是不安全的。开启它意味着前端可以伪造Host、Origin等敏感头,可能被用来绕过后端的安全校验。除非你明确知道需要它,否则别开。
Rust 端:reqwest 重导出
HTTP 插件在 Rust 端直接重导出了 reqwest crate——Rust 生态中最流行的 HTTP 客户端库。你不需要单独在 Cargo.toml 里加 reqwest 依赖,直接用插件导出的就行:
use tauri_plugin_http::reqwest;
// GET 请求
let res = reqwest::get("https://api.tauri.app/data.json").await?;
println!("{}", res.status()); // 200
let body = res.text().await?;
println!("{}", body); // 响应体文本
要发 POST 请求或自定义请求,用 Client:
use tauri_plugin_http::reqwest;
let client = reqwest::Client::new();
let res = client
.post("https://api.tauri.app/submit")
.json(&serde_json::json!({
"name": "Tauri",
"version": "2"
}))
.send()
.await?;
println!("{}", res.status());
Rust 端的请求不受 URL 白名单限制——白名单只约束前端 JS。Rust 端是你自己的代码,不存在「被注入」的风险。但这也意味着你要自己注意别请求不安全的地方。
TipRust 端用
reqwest时,可以充分利用它的所有高级功能:超时设置、重定向策略、TLS 证书自定义、代理等。这些在reqwest::ClientBuilder上都有对应的方法。比如.timeout(Duration::from_secs(30))设置超时,.danger_accept_invalid_certs(true)跳过证书验证(仅开发调试用)。
连接超时与代理配置
前端 fetch 不直接暴露超时和代理设置,但你可以通过 Rust 端的 reqwest::ClientBuilder 来配置这些。一个常见的做法是在 Rust 端创建好配置好的 Client,然后通过 Tauri 命令暴露给前端用:
use tauri_plugin_http::reqwest;
use std::time::Duration;
#[tauri::command]
async fn fetch_api(url: String) -> Result<String, String> {
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()
.map_err(|e| e.to_string())?;
let res = client
.get(&url)
.send()
.await
.map_err(|e| e.to_string())?;
res.text().await.map_err(|e| e.to_string())
}
这样前端调 fetch_api 命令就行,超时由 Rust 端控制。代理配置类似,用 .proxy(reqwest::Proxy::all("http://proxy:8080")?) 即可。
Note如果你需要更复杂的网络配置(自定义 CA 证书、客户端证书认证、SOCKS5 代理等),建议直接在 Rust 端用
reqwest::ClientBuilder处理,然后通过 Tauri 命令暴露给前端。前端fetch适合简单的请求场景,复杂场景走 Rust 命令更灵活。
小结
tauri-plugin-http 让 Tauri 应用具备发 HTTP 请求的能力:前端用 fetch 函数,API 和浏览器 Fetch API 几乎一致,但请求实际在 Rust 端执行,绕过了 CORS 限制。安全上通过 capability 里的 URL 白名单(allow / deny + 通配符)控制前端能访问哪些地址。默认禁用部分敏感请求头,需要时可在 Cargo.toml 开启 unsafe-headers 特性。Rust 端重导出了 reqwest crate,支持完整的 HTTP 客户端功能,包括超时、代理、证书等高级配置。简单请求用前端 fetch,复杂网络配置走 Rust 命令,两者搭配覆盖大部分场景。