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

使用aws-sdk/client-s3删除DigitalOcean Spaces多文件遇501错误求助

DigitalOcean Spaces批量删除文件遇501 NotImplemented错误

问题详情

尝试从DigitalOcean Spaces中批量删除文件时持续报错,所有环境变量已正确配置。

当前代码

const { S3Client, DeleteObjectsCommand } = require("@aws-sdk/client-s3");
require("dotenv").config();

const s3 = new S3Client({
  region: "sfo3", 
  credentials: {
    accessKeyId: process.env.DO_SPACES_KEY, 
    secretAccessKey: process.env.DO_SPACES_SECRET, 
  },
  endpoint: process.env.DO_SPACES_ENDPOINT,
  forcePathStyle: true, // Required for some S3-compatible services
});

const deleteFile = async (keys) => {
  try {
    const keys = [
      "1702039720121672541410-file_example_JPG_2500kB.jpg",
      "1702034408592871178538-file_example_PNG_2100kB.png",
      "1702034501011992084344-file_example_PNG_3MB.png",
    ];
    const keysArray = [];
    keys.map((key) => keysArray.push({ Key: key }));
    console.log(keysArray);
    const deleteParams = {
      Bucket: process.env.DO_SPACES_NAME, 
      Delete: {
        Objects: keysArray,
        // Quiet: false, 
      },
    };

    const command = new DeleteObjectsCommand(deleteParams);
    const data = await s3.send(command).catch((err) => {
      console.log(err);
    });

    console.log(data);
    return data;
  } catch (error) {
    console.error("Error deleting file:", error);
    throw error;
  }
};

module.exports = deleteFile;

收到的错误信息

NotImplemented: UnknownError
    at throwDefaultError (C:\Users\username\Desktop\skrink-image\backend\node_modules\@smithy\smithy-client\dist-cjs\default-error-handler.js:8:22)
{
  '$fault': 'client',
  '$metadata': {
    httpStatusCode: 501,
    requestId: 'tx0000016e999caa939aed5-00657a18e7-3c6e5030-sfo3a',
    extendedRequestId: undefined,
    cfId: undefined,
    attempts: 1,
    totalRetryDelay: 0
  },
  Code: 'NotImplemented',
  RequestId: 'tx0000016e999caa939aed5-00657a18e7-3c6e5030-sfo3a',
  HostId: '3c6e5030-sfo3a-sfo3-zg01'
}

已尝试的操作

  • 将forcePathStyle设为false
  • 使用aws-sdk v2版本
    以上两种方法均未解决问题。

package.json配置

{
  "name": "backend",
  "version": "1.0.0",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "nodemon server.js",
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@aws-sdk/client-s3": "^3.472.0",
    "@img/sharp-win32-x64": "^0.33.0",
    "aws-sdk": "^2.1515.0",
    "body-parser": "^1.20.2",
    "cors": "^2.8.5",
    "dotenv": "^16.3.1",
    "express": "^4.18.2",
    "fs-extra": "^11.2.0",
    "joi": "^17.11.0",
    "multer": "^1.4.5-lts.1",
    "mysql2": "^3.6.5",
    "node-cron": "^3.0.3",
    "nodemon": "^3.0.2",
    "sequelize": "^6.35.1",
    "sharp": "^0.33.0"
  },
  "devDependencies": {
    "sequelize-cli": "^6.6.2"
  }
}

解决方法

1. 修正Endpoint格式

DigitalOcean Spaces的标准Endpoint格式为https://<region>.digitaloceanspaces.com(比如sfo3区域对应https://sfo3.digitaloceanspaces.com),确保环境变量DO_SPACES_ENDPOINT没有包含Bucket名称,也不是未配置CNAME的自定义域名。

2. 调整forcePathStyle配置

DigitalOcean Spaces采用虚拟主机风格路径,需将forcePathStyle设为false,这是适配DO Spaces的关键配置。

3. 修复代码参数覆盖问题

你的deleteFile函数接收了keys参数,但内部又重新定义了同名变量覆盖传入值,建议移除内部的const keys = [...],直接使用传入的参数。

4. 修正后的完整代码

const { S3Client, DeleteObjectsCommand } = require("@aws-sdk/client-s3");
require("dotenv").config();

const s3 = new S3Client({
  region: "sfo3",
  credentials: {
    accessKeyId: process.env.DO_SPACES_KEY,
    secretAccessKey: process.env.DO_SPACES_SECRET,
  },
  endpoint: `https://${process.env.DO_SPACES_REGION || "sfo3"}.digitaloceanspaces.com`,
  forcePathStyle: false,
});

const deleteFile = async (keys) => {
  try {
    const keysArray = keys.map(key => ({ Key: key }));
    const deleteParams = {
      Bucket: process.env.DO_SPACES_NAME,
      Delete: {
        Objects: keysArray,
        Quiet: false
      },
    };

    const command = new DeleteObjectsCommand(deleteParams);
    const data = await s3.send(command);
    console.log("删除成功:", data);
    return data;
  } catch (error) {
    console.error("删除失败:", error);
    throw error;
  }
};

module.exports = deleteFile;

5. 验证权限

确保你的DO Spaces密钥拥有s3:DeleteObject权限,对应的IAM策略需包含:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:DeleteObject",
      "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*"
    }
  ]
}

6. 先测试单个文件删除

如果批量删除仍报错,先使用DeleteObjectCommand测试单个文件删除,确认单个操作正常后再尝试批量,排查是否为批量接口的适配问题。


内容的提问来源于stack exchange,提问作者Shamoil khan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 23:13:17