云存储 - 元数据部分太大

Cloud Storage - metadata part is too large

我们的应用程序中有照片上传功能,适用于很多人,但有些人会遇到以下错误:

"{
    "responseData": "Metadata part is too large."
}
"

尝试上传文件时。

我使用 Google Cloud Storage 使用 FormData() 通过 POST 使用签名的策略文档上传文件。

这是我使用nodejs最新的云存储库(5.18.1)发布策略的方式:

        const gcsClient = new Storage({
            projectId: EnvConfig.gcpProjectId,
            credentials: getGoogleCloudStorageCredentials ()
        });

        const policyOpts = {
            equals: ['$Content-Type', contentType],
            expires: getTodaysDateSecondsAdded(900),
            contentLengthRange: {
                min: 0,
                max: 20000000 // 20MB
            }
        };

        const [{ base64, signature, string }] = await gcsClient
            .bucket(EnvConfig.gcpUploadBucket)
            .file(fileName)
            .getSignedPolicy(policyOpts);

这是上传的方式:

    const data = new FormData();

    data.append('policy', policy64);
    data.append('signature', policySignature);
    data.append('file', {uri: sourceUrl, type: contentType});
    data.append('key', fileName);
    data.append('GoogleAccessId', googleAccessId);
    data.append('Content-Type', contentType);

    const CancelToken = axios.CancelToken;
    const source = CancelToken.source();


    try {
          await axios.post(uploadUrl, data);
    } catch (e) {

      if (axios.isCancel(e)) {
        throw new Error(`axios upload image failed due to timeout`);
      }

      throw e;
    }

我对引用的元数据部分感到困惑?我们是在谈论作为云存储概念一部分的对象元数据吗?如果是,我无法控制它,我没有在任何地方添加任何元数据?还是我们在谈论图像元数据本身?

这只是一个严重的错误吗?它实际上意味着文件太大了吗?

据此:

“所有自定义元数据键和值的最大组合大小限制为每个对象 8 KiB。” - https://cloud.google.com/storage/quotas

所以我目前的假设是某个地方生成了一个超过 8KB 的魔法对象元数据,云存储中是否有一些未记录的逻辑部分自动从 POST 请求中提取自定义元数据?

我看到了一堆可能的重复项,但没有答案:

问题在于您如何传入文件:

    data.append('file', {uri: sourceUrl, type: contentType});

这实际上并不是您想要的设置文件。我相信该文件是作为常规表单数据传递的,而不是 multipart/form-data 上传中的单独部分,因此超出了限制。这种调用格式没有出现在FormData doc you linked.

相反,尝试实际创建一个文件对象来传递:

    data.append('file', f /*an instance of File or Blob*/);

经过几个月的调试,我想通了,

基本上当附加文件到表单数据时,您还需要指定名称:否则对于大于 4MB+ 的大文件将失败。

之前(一直失败):

data.append('file', { uri: assetUri, type: contentType});

之后:

data.append('file', { uri: assetUri, type: contentType, name: 'dummy.jpg' });

如果您阅读 react-native 源代码,您会看到“名称”将在 multipart/formdata 请求

中强制发出 filename=

https://issuetracker.google.com/issues/225060183