很多人在 Tauri v2(尤其是 Linux 系统)中使用 convertFileSrc() 或 asset://localhost 协议加载本地图片、视频、音频等资源时,经常遇到 403 Forbidden 错误。Windows/macOS 可能正常,Linux 却直接翻车。
本文把整个坑的来龙去脉、根本原因、glob 匹配规则彻底讲清楚,并给出最稳的配置方案,帮助大家一次性避坑。
一、问题现象
-
使用
convertFileSrc(fullPath)生成的 URL 在<img>、<video>、<audio>等标签中加载失败 -
浏览器控制台报 403
-
终端(Rust 侧)日志提示类似:
javascriptasset protocol not configured to allow the path: /home/user/.local/share/xxx/xxx.png -
尤其容易出现在 隐藏目录 (以
.开头的目录)下:.local/share、.cache、.config等
二、根本原因:Tauri 的 Glob Scope + Linux 隐藏目录规则
Tauri v2 的 assetProtocol.scope 使用的是 Rust globset 库实现的 glob 模式来做安全校验。只有路径匹配 scope 里的 glob,才允许浏览器通过 asset 协议访问。
最坑的一点在于,Linux(Unix-like 系统)下:
通配符
*、?、**等 默认不会匹配以.开头的路径 (dotfiles / dotdirs),除非你在 glob 模式里字面写出.。
所以即使你写了最宽松的 "**/*",它也进不了 .local、.cache 等隐藏目录,导致 403。
这不是 bug,而是 Tauri 为了安全故意设计的(和 Linux shell 的 ls * 默认不显示隐藏文件一样)。
三、Glob 模式最容易搞混的两个写法:**/ vs **/*
| glob 写法 | 含义 | 能匹配什么 | 在 assetProtocol.scope 里的实际效果 | 推荐程度 |
|---|---|---|---|---|
**/* |
递归匹配所有文件 | 文件(如 a.png、sub/b.mp4) |
✅ 强烈推荐 | ★★★★★ |
**/ |
递归匹配所有目录 | 纯目录路径(如 images/、sub/) |
❌ 几乎没用(scope 要的是文件路径) | ★☆☆☆☆ |
一句话总结:
**/*= "递归所有文件"(你 99% 的情况都需要这个)**/= "递归所有目录"(基本不要单独写在 scope 里)
正确写法是 你的路径/**/* 或直接 **/*
四、正确配置(一步到位)
1. 主配置(推荐同时加 Linux 专属配置)
src-tauri/tauri.conf.json(全局):
json
{
"app": {
"security": {
"csp": "default-src 'self' ipc: http://ipc.localhost; img-src 'self' asset: http://asset.localhost; video-src 'self' asset: http://asset.localhost; audio-src 'self' asset: http://asset.localhost; style-src 'self' 'unsafe-inline';",
"assetProtocol": {
"enable": true,
"scope": [
"**/*",
"**/.local/share/**/*",
"**/.cache/**/*",
"$CACHE/**",
"$CONFIG/**",
"$HOME/**"
]
}
}
}
}
src-tauri/tauri.linux.conf.json(Linux 专属,强烈建议):
json
{
"app": {
"security": {
"assetProtocol": {
"enable": true,
"scope": [
"**/*",
"**/.local/share/**/*",
"**/.cache/**/*",
"$CACHE/**",
"$CONFIG/**"
]
}
}
}
}
这样 Windows/macOS 不会被多余的 scope 影响。
2. 代码侧使用(不变)
ts
import { convertFileSrc } from '@tauri-apps/api/core';
const assetUrl = convertFileSrc(absoluteFilePath);
五、操作流程
- 按上面修改配置文件
- (推荐)
cargo clean pnpm tauri dev(或npm run tauri dev)测试- 还是 403?看终端日志,把报错里提示的路径对应的 glob 补进去
六、额外避坑小贴士
- 用 Tauri 内置变量
$CACHE、$CONFIG最香,自动处理平台差异 - 如果是用户通过
dialog.open()选择的路径,Tauri 会自动扩展 scope,但持久化路径仍需写进配置 - 打包进 bundle 的资源不需要 assetProtocol,走
frontendDist即可 - Rust 版本建议 ≥ 1.77,Tauri CLI 保持最新
总结 :
Tauri 2 的 asset 403 坑,99% 是因为 Linux 下 glob 默认不匹配 . 开头的隐藏目录 。只要把 **/* + **/.local/share/**/* + $CACHE/** 写全,问题基本秒解。
把这篇配置直接复制到你的项目里,基本不会再踩这个坑了。
希望这篇文章能帮到更多 Tauri 开发者少走弯路!
如果你还有其他 Tauri v2 的奇葩问题,欢迎继续留言~