NextJS 13中如何使用UploadThing删除文件?
解决NextJS 13中UploadThing删除文件的服务器端API限制问题
你遇到的错误是因为utapi是UploadThing的服务器端专属API,不能直接在客户端组件中调用。必须把删除逻辑放在服务器环境(API路由、服务器动作)中,客户端通过请求或调用服务器动作触发删除操作。
以下是两种可行的实现方案:
方案一:使用Next.js API路由(兼容Pages/App Router)
1. 创建API路由文件
在src/app/api/delete-file/route.ts(App Router)或src/pages/api/delete-file.ts(Pages Router)中编写服务器端删除逻辑:
import { utapi } from "@/server/delete"; import { NextResponse } from "next/server"; // App Router 写法 export async function DELETE(request: Request) { const { fileKey } = await request.json(); if (!fileKey) { return NextResponse.json({ error: "文件Key不能为空" }, { status: 400 }); } try { const deleteResult = await utapi.deleteFiles(fileKey); return NextResponse.json(deleteResult); } catch (err) { return NextResponse.json({ error: "删除文件失败" }, { status: 500 }); } } // Pages Router 写法(可选) // export default async function handler(req, res) { // if (req.method !== 'DELETE') { // return res.status(405).json({ error: "仅支持DELETE请求" }); // } // const { fileKey } = req.body; // if (!fileKey) return res.status(400).json({ error: "文件Key不能为空" }); // try { // const result = await utapi.deleteFiles(fileKey); // res.status(200).json(result); // } catch (err) { // res.status(500).json({ error: "删除文件失败" }); // } // }
2. 修改客户端组件调用API
更新你的deleteImage.js组件,通过fetch调用API路由:
'use client'; import React from 'react' const DeleteImage = () => { const testDelete = async () => { console.log("开始删除文件") try { const response = await fetch('/api/delete-file', { method: 'DELETE', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ fileKey: "b0e3a5bc-dd85-40fe-9a0c-59d2ece0bb60-4ulhix.png" }) }); const data = await response.json(); console.log("删除结果:", data); } catch (error) { console.error("删除失败:", error); } } return ( <div> <h1>测试图片删除</h1> <button onClick={testDelete}>删除文件</button> </div> ) } export default DeleteImage
方案二:使用Next.js 13+服务器动作(App Router推荐)
1. 定义服务器动作
在src/server/actions.ts中创建带'use server'指令的服务器动作:
'use server'; import { utapi } from "./delete"; export async function deleteFile(fileKey: string) { if (!fileKey) { throw new Error("文件Key不能为空"); } try { return await utapi.deleteFiles(fileKey); } catch (err) { throw new Error("删除文件失败"); } }
2. 客户端组件调用服务器动作
更新客户端组件,直接调用服务器动作:
'use client'; import React from 'react' import { deleteFile } from '@/server/actions'; const DeleteImage = () => { const testDelete = async () => { console.log("开始删除文件") try { const result = await deleteFile("b0e3a5bc-dd85-40fe-9a0c-59d2ece0bb60-4ulhix.png"); console.log("删除结果:", result); } catch (error) { console.error("删除失败:", error); } } return ( <div> <h1>测试图片删除</h1> <button onClick={testDelete}>删除文件</button> </div> ) } export default DeleteImage
注意事项
- 确保
.env文件中已正确配置UploadThing的密钥:UPLOADTHING_SECRET=你的密钥 - 客户端组件必须添加
'use client'指令(App Router下默认是服务器组件,无法处理交互) - 服务器动作和API路由都运行在服务器环境,不会暴露你的UploadThing密钥
内容的提问来源于stack exchange,提问作者Thibaut
相关产品推荐
相关产品推荐

