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

如何在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"
}

解决方法

核心问题说明

  1. Cloudinary的destroy删除接口不能复用上传返回的signature,每个操作的签名需要单独生成
  2. 绝对不能在前端暴露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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 04:48:29