如何在Next.js中使用Axios删除Cloudinary中的图片文件?
在Next.js中删除Cloudinary上传图片的问题
我在Next.js中实现了图片上传到Cloudinary的流程,上传功能正常,已经将返回的public_id、signature保存到imageData状态中,同时也存储了我的云服务API密钥。但尝试用Axios发送POST请求删除刚上传的图片时出现错误,换成axios.delete()同样无法正常工作。
相关代码如下:
export default function Home() { const [img, setImg] = useState(""); const [imageData, setImageData] = useState({ url: "", public_id: "", signature: "", api_key: "", }); const updateImage = (e) => { setImg(e.target.files[0]); }; const uploadImage = async (e) => { e.preventDefault(); const data = new FormData(); data.append("file", img); data.append("upload_preset", "cloudinary_default"); try { const response = await axios.post( `https://api.cloudinary.com/v1_1/<cloud_name>/image/upload`, data ); setImageData({ url: response.data.url, public_id: response.data.public_id, signature: response.data.signature, api_key: <my_api_key>, }); } catch (error) { console.log(`error from axios post`, error); } }; const deleteImage2 = async (e) => { e.preventDefault(); const timestamp = new Date().getTime() const formData = new FormData(); formData.append("public_id", imageData.public_id); formData.append("signature", imageData.signature); formData.append("api_key", imageData.api_key); formData.append("timestamp",timestamp) const res = await axios.post( "https://api.cloudinary.com/v1_1/<cloud_name>/image/destroy", formData ); console.log("response from delete: ", res); }; return ( <div> <form> <input type="file" onChange={updateImage} /> <button onClick={uploadImage}>Upload</button> <button onClick={deleteImage}>Remove</button> </form> </div> ); }
uploadImage函数返回的数据示例:
data: { access_mode: "public" asset_id: "a2cfdb456108e23d154520f913e1b5d5" bytes: 635033 created_at: "2022-08-27T08:32:13Z" etag: "5d2518ce194a66abd33a9a966a86350e" folder: "" format: "jpg" height: 4167 original_filename: "asdf.png" placeholder: false public_id: "uk66y5akqeyfyiwebxed" resource_type: "image" secure_url: "https://res.cloudinary.com/<cloud_name>/image/upload/v1661589133/uk66y5akqeyfyiwebxed.jpg" signature: "cc836688d98fae0d57b629e2d402c6a670217d95" }
解决方法
核心问题说明
- Cloudinary的
destroy删除接口不能复用上传返回的signature,每个操作的签名需要单独生成 - 绝对不能在前端暴露API密钥,Cloudinary会直接拒绝前端发起的带密钥的删除请求,这也是严重的安全风险
具体实现步骤
1. 把删除逻辑移到Next.js后端API路由
在pages/api目录下新建delete-cloudinary-image.js文件,用Cloudinary官方SDK处理删除:
// pages/api/delete-cloudinary-image.js import cloudinary from 'cloudinary'; // 配置Cloudinary,建议用环境变量存储敏感信息,不要硬编码 cloudinary.config({ cloud_name: process.env.CLOUDINARY_CLOUD_NAME, api_key: process.env.CLOUDINARY_API_KEY, api_secret: process.env.CLOUDINARY_API_SECRET, }); export default async function handler(req, res) { // 仅接受POST请求 if (req.method !== 'POST') { return res.status(405).json({ message: '仅支持POST请求' }); } const { public_id } = req.body; try { // 调用Cloudinary的删除方法 const result = await cloudinary.uploader.destroy(public_id); res.status(200).json(result); } catch (error) { res.status(500).json({ error: error.message }); } }
2. 修改前端删除函数,调用自己的后端API
const deleteImage2 = async (e) => { e.preventDefault(); try { const res = await axios.post('/api/delete-cloudinary-image', { public_id: imageData.public_id }); console.log("删除响应: ", res.data); // 删除成功后清空状态 setImageData({ url: "", public_id: "", signature: "", api_key: "" }); } catch (error) { console.error("删除失败: ", error); } };
3. 补充配置
在项目根目录的.env.local文件中添加Cloudinary环境变量:
CLOUDINARY_CLOUD_NAME=你的cloud_name CLOUDINARY_API_KEY=你的api_key CLOUDINARY_API_SECRET=你的api_secret
内容的提问来源于stack exchange,提问作者Nasem
相关产品推荐
相关产品推荐

