如何将Tauri的File-Drop事件转换为真实File对象用于接口上传
Tauri 窗口拖拽文件转标准File对象实现方案
Tauri 自带的文件拖拽事件默认不会直接返回 Web 标准File实例,仅会返回被拖拽文件的本地绝对路径,你可以通过路径读取文件内容手动构造File实例,即可直接塞入FormData完成接口上传,具体实现如下:
前置权限配置
首先需要在项目配置中开启文件读取权限,否则无法读取拖拽文件的内容:
- Tauri v1 版本:在
tauri.conf.json的allowlist配置项中添加fs权限:{ "tauri": { "allowlist": { "fs": { "readBinaryFile": true, "scope": ["**"] } }, "windows": [ { "fileDropEnabled": true } ] } } - Tauri v2 版本:在能力配置文件(通常是
src-tauri/capabilities/default.json)中添加fs读取权限:{ "permissions": [ "fs:allow-read-file", { "identifier": "fs:allow-read-file", "allow": [{ "path": "**" }] } ] }
代码实现
注意:不要使用Web原生的dragover/drop事件监听系统文件拖拽,Tauri默认会拦截窗口层的系统拖拽行为,Web原生拖拽事件无法拿到有效文件数据,直接监听Tauri提供的拖拽完成事件即可:
// Tauri v2 引入方式 import { listen } from '@tauri-apps/api/event' import { readFile } from '@tauri-apps/plugin-fs' import { basename } from '@tauri-apps/api/path' // Tauri v1 请替换为以下引入方式 // import { listen } from '@tauri-apps/api/event' // import { readBinaryFile } from '@tauri-apps/api/fs' // import { basename } from '@tauri-apps/api/path' // 监听拖拽完成事件(鼠标松开、文件落区时触发) listen('tauri://file-drop', async (event) => { // payload 为所有拖拽文件/文件夹的本地绝对路径数组 const filePaths = event.payload const formData = new FormData() for (const filePath of filePaths) { // v2 读文件方法 const fileBuffer = await readFile(filePath) // v1 请替换为 const fileBuffer = await readBinaryFile(filePath) // 提取文件名 const fileName = await basename(filePath) // 构造标准Web File对象 const fileInstance = new File([fileBuffer], fileName, { // 可根据文件后缀自行扩展MIME类型映射,不传不影响基础上传功能 type: getFileMimeType(fileName) }) formData.append('uploadFiles', fileInstance) } // 后续直接复用Web端上传逻辑即可 // await fetch('/your/upload/endpoint', { // method: 'POST', // body: formData // }) }) // 简易MIME类型匹配工具,可按需扩展 function getFileMimeType(fileName) { const ext = fileName.split('.').pop()?.toLowerCase() const mimeMap = { png: 'image/png', jpg: 'image/jpeg', jpeg: 'image/jpeg', gif: 'image/gif', pdf: 'application/pdf', doc: 'application/msword', docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', txt: 'text/plain' } return mimeMap[ext] || 'application/octet-stream' }
注意事项
- 如果拖拽目标包含文件夹,事件只会返回文件夹本身的路径,不会自动递归遍历内部文件,需要自行引入目录遍历逻辑读取子文件
- 大文件场景下不建议一次性将整个文件读入内存,可配合Tauri的fs分片读取逻辑+分片上传实现大文件传输,避免应用卡顿
- 如果不需要读取文件内容、仅需把文件路径传给后端处理,可以直接传
event.payload里的路径,不需要构造File实例
内容的提问来源于stack exchange,提问作者Lorix
相关产品推荐
相关产品推荐

