You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 12:01:06