云存储 - 元数据部分太大
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=
我们的应用程序中有照片上传功能,适用于很多人,但有些人会遇到以下错误:
"{
"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=