【问题标题】:Google cloud Storage ApiError: Required谷歌云存储 ApiError:必需
【发布时间】:2021-11-14 22:14:11
【问题描述】:

将文件上传到 Bucket 时出现错误。我尝试了所有方法,但每次都收到此错误。我的存储桶名称和本地路径(文件路径)是正确的。我不知道这里需要什么。

ApiError: Required
at processTicksAndRejections (internal/process/task_queues.js:95:5) {
  code: 400,
  errors: [ { message: 'Required', domain: 'global', reason: 'required' } ],
  response: 
    ...
    allowHalfOpen: true,
    statusCode: 400,
    statusMessage: 'Bad Request',
    request: {
      agent: [Agent],
      headers: [Object],
      href: 'https://storage.googleapis.com/upload/storage/v1/b/demo-bucket-log0/o?uploadType=multipart&name=demo.log'
    },
    body: '{\n' +
      '  "error": {\n' +
      '    "code": 400,\n' +
      '    "message": "Required",\n' +
      '    "errors": [\n' +
      '      {\n' +
      '        "message": "Required",\n' +
      '        "domain": "global",\n' +
      '        "reason": "required"\n' +
      '      }\n' +
      '    ]\n' +
      '  }\n' +
      '}\n',
    ...
}

给出错误的代码如下。

function createBlob(bucketName, name, localFilePath) {
    return new Promise((resolve, reject) => {
        const bucket = gcpStorage.bucket(bucketName);
        bucket.upload(localFilePath).then(() => resolve("sucess")).catch((err) => reject(err))
    });
}

【问题讨论】:

  • 你能再分享一些代码吗?我们在哪里可以看到这个函数是如何被调用的?
  • 我无法重现此问题。我刚刚再次安装了软件包,它对我有用。

标签: node.js google-cloud-platform google-cloud-storage


【解决方案1】:

当我尝试download() 一个文件时,我遇到了同样的问题,并且得到了一个 json 响应而不是预期的缓冲区。

我可以解决它的唯一方法是删除我的 yarn.lock 并再次运行 yarn 以重新创建它。

【讨论】:

  • 我也做过同样的事情。不知道为什么会这样。
【解决方案2】:

感谢@Justin Bender,我想没有比这更简单的了:

const { Storage } = require("@google-cloud/storage");
const storage = new Storage({keyFilename: "mykeyfile.json"});

async function uploadFile() {
  try {
    return await storage.bucket("mybucket").upload("test.txt", {
      destination: "test.txt",
    });
  } catch (err) {
    console.error(err);
  }
}

uploadFile().then(() => console.log("done")).catch((err) => console.error("error"));

这是返回的内容:

ApiError: Required
    at new ApiError (/.../node_modules/@google-cloud/common/build/src/util.js:73:15)
    at Util.parseHttpRespBody (/.../node_modules/@google-cloud/common/build/src/util.js:208:38)
    at Util.handleResp (/.../node_modules/@google-cloud/common/build/src/util.js:149:117)
    at /.../node_modules/@google-cloud/common/build/src/util.js:479:22
    at onResponse (/.../node_modules/retry-request/index.js:228:7)
    at /.../node_modules/teeny-request/build/src/index.js:157:17
    at processTicksAndRejections (internal/process/task_queues.js:93:5) {
...
body: '{\n' +
      '  "error": {\n' +
      '    "code": 400,\n' +
      '    "message": "Required",\n' +
      '    "errors": [\n' +
      '      {\n' +
      '        "message": "Required",\n' +
      '        "domain": "global",\n' +
      '        "reason": "required"\n' +
      '      }\n' +
      '    ]\n' +
      '  }\n' +
      '}\n',

我在 macos 上尝试过 Node 14、16 和 @google-cloud/storage@5.16.0、5.8.5 和 4.7.2 的版本。只有 v4 有效。

然后我尝试通过 REST 上传文件(包括生成令牌)并且它工作正常,因此存储桶和密钥文件都按预期工作。

深入研究 gaxios 库,我可以确认令牌生成有效,只有实际的上传请求由于某种原因失败。

【讨论】:

    【解决方案3】:

    @Pruthvi Hingu 你看过文章Google Cloud Storage Upload Object Nodejs

    Google Cloud 上传文档

    // The ID of your GCS bucket
    const bucketName = 'your-unique-bucket-name';
    
    // The path to your file to upload
    const filePath = 'path/to/your/file';
    
    // The new ID for your GCS file
    const destFileName = 'your-new-file-name';
    
    // Imports the Google Cloud client library
    const {Storage} = require('@google-cloud/storage');
    
    // Creates a client
    const storage = new Storage();
    
    async function uploadFile() {
      await storage.bucket(bucketName).upload(filePath, {
        destination: destFileName,
      });
    
      console.log(`${filePath} uploaded to ${bucketName}`);
    }
    
    uploadFile().catch(console.error);
    

    我认为您的代码运行不正常,不妨试试这样的方法

    function createBlob(bucketName, name, localFilePath) {
        // creating promise
        return new Promise((resolve, reject) => {
            gcpStorage.bucket(bucketName).upload(localFilePath).then(data => {
                    resolve("sucess", data);
                }).catch((error) => reject(error));
            }
        }).catch((err) => console.log(err));
    }
    

    【讨论】:

    • 是的。我读过。我还将服务帐户密钥路径和 projectId 传递给了 Storage() 构造函数。
    • @PruthviHingu 为什么你不使用异步和等待。为什么是新的 Promise?
    • 这是一个小项目的一部分。即使我删除了 Promise,我也会遇到同样的错误。
    • @PruthviHingu 我添加到我的答案中是为了给函数一个执行顺序,而不是让它们运行先完成的那个。
    猜你喜欢
    • 2020-09-10
    • 2016-10-12
    • 1970-01-01
    • 1970-01-01
    • 2012-08-19
    • 2017-01-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多