[英]AWS S3 multipart / uploadPart silent fail from browser JS SDK
I'm trying a multipart s3 upload from the browser with the JS SDK. 我正在尝试使用JS SDK从浏览器进行多部分s3上传。 I have no trouble with createMultipartUpload, but I get no data back from uploadPart. 我对createMultipartUpload没问题,但是我没有从uploadPart返回任何数据。 I can't call completeMultipartUpload because I don't get any eTags back. 我无法调用completeMultipartUpload,因为我没有收回任何eTag。 I get the $response part of the object only, which indicates a 200 status and that all the parameters I passed were defined and the proper datatypes. 我仅获得对象的$ response部分,它指示200状态,并且定义了我传递的所有参数和正确的数据类型。 I can't see any of the parts in my bucket, although I don't know if they're going to a special "parts" place that I can't access. 我看不到存储桶中的任何零件,尽管我不知道它们是否要进入我无法访问的特殊“零件”位置。
Here's my code: 这是我的代码:
const createParams = {
Bucket,
Key: `${uuid()}.${getExtension(file.type)}`,
ContentType: file.type,
ContentDisposition: 'attachment'
}
return s3.createMultipartUpload(createParams).promise()
.then(result => {
console.log(result);
console.log('chunking...')
let chunkArr = chunker(file);
let chunkMap = Promise.map(chunkArr, (chunk, index) => {
const chunkParams = {
Body: chunk,
Bucket: result.Bucket,
Key: result.Key,
PartNumber: index + 1,
UploadId: result.UploadId,
ContentLength: chunk.size
}
console.log(chunkParams)
return s3.uploadPart(chunkParams).promise();
});
return Promise.all(chunkMap);
})
.then(result => {
console.log(result);
return Promise.resolve(true)
// let stopParams = {
//
// }
// return s3.completeMultipartUpload(stopParams).promise();
})
.catch(err => {
throw err;
return Promise.reject(err);
});
s3 instance looks like this: s3实例如下所示:
import AWS from 'aws-sdk';
AWS.config.setPromisesDependency(Promise);
const s3 = new AWS.S3({
apiVersion: '2006-03-01',
accessKeyId: credentials.credentials.AccessKeyId,
secretAccessKey: credentials.credentials.SecretAccessKey,
sessionToken: credentials.credentials.SessionToken,
sslEnabled: true,
s3ForcePathStyle: true,
httpOptions: {
xhrAsync: true,
xhrWithCredentials: true
}
})
chunker function looks like this: 块函数如下所示:
const chunkFile = (file) => {
console.log(typeof(file));
const fileSize = file.size;
const chunkSize = 5242881; // bytes
let offset = 0;
let chunkArr = [];
const chunkReaderBlock = (_offset, _file) => {
console.log(_offset);
if (_offset >= fileSize) {
console.log("Done reading file");
return chunkArr;
}
let blob = _file.slice(_offset, chunkSize + _offset);
console.log(blob);
console.log(typeof(blob));
chunkArr.push(blob);
return chunkReaderBlock(chunkSize + _offset, _file);
}
return chunkReaderBlock(offset, file);
}
The response object I'm getting back looks like this: 我返回的响应对象如下所示:
(2)[{…}, {…}]
0: {
$response: Response
}
1: $response: Response
cfId: undefined
data: {
$response: Response
}
error: null
extendedRequestId: undefined
httpResponse: HttpResponse
body: Uint8Array[]
headers: {}
statusCode: 200
statusMessage: "OK"
stream: EventEmitter {
_events: {…},
_maxListeners: undefined,
statusCode: 200,
headers: {…}
}
streaming: false
_abortCallback: ƒ callNextListener(err) __proto__: Object
maxRedirects: 10
maxRetries: 3
redirectCount: 0
request: Request {
domain: undefined,
service: f… s.constructor,
operation: "uploadPart",
params: {…},
httpRequest: HttpRequest,
…
}
retryCount: 0
__proto__: Object
__proto__: Object
length: 2
__proto__: Array(0)
Any ideas? 有任何想法吗? This is in React and my test file is 9.xx MB. 这在React中,我的测试文件是9.xx MB。 I also tried with callbacks, and uploading one part at a time, and got the same thing. 我还尝试了回调,并且一次上传了一部分,并且得到了相同的结果。
In a cross-origin context, you'd need this in your bucket's CORS configuration: 在跨域上下文中,您需要在存储桶的CORS配置中使用此功能:
<ExposeHeader>ETag</ExposeHeader>
ExposeHeader
— Identifies the response headers ... that customers will be able to access from their applications (for example, from a JavaScript XMLHttpRequest object)."ExposeHeader
—标识响应标头……客户将能够从其应用程序(例如,从JavaScript XMLHttpRequest对象)访问该响应标头。”https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html
To clarify what's going in here, CORS isn't an access restriction mechanism -- it's a mechanism for giving the browser permission to do something that it otherwise assumes might not be something the user would want to happen. 为了阐明这里发生的情况,CORS不是访问限制机制,而是一种机制,用于授予浏览器执行某些操作的权限,否则该操作可能会假定用户可能不想执行此操作。 It tells the browser to give JavaScript permission to do and see things that would not otherwise be allowed. 它告诉浏览器授予JavaScript权限来执行操作,并查看原本不允许的操作。
From the Mozilla CORS documentation: 从Mozilla CORS文档中:
By default, only the 6 simple response headers are exposed: 默认情况下,仅公开6个简单响应头:
Cache-Control
Content-Language
Content-Type
Expires
Last-Modified
Pragma
Cache-Control
Content-Language
Content-Type
Expires
Last-Modified
Pragma
If you want clients to be able to access other headers, you have to list them using the
Access-Control-Expose-Headers
header. 如果希望客户端能够访问其他标头,则必须使用Access-Control-Expose-Headers
标头列出它们。https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers
In S3, the way you set the Access-Control-Expose-Headers
response header is by configuring <ExposeHeaders>
(above). 在S3中,设置Access-Control-Expose-Headers
响应标头的方式是通过配置<ExposeHeaders>
(如上)。 Otherwise, JavaScript can't see them. 否则,JavaScript将看不到它们。
I can't see any of the parts in my bucket, although I don't know if they're going to a special "parts" place that I can't access. 我看不到存储桶中的任何零件,尽管我不知道它们是否要进入我无法访问的特殊“零件”位置。
They are. 他们是。 Use the listMultipartUploads
to find abandoned uploads, and abortMultipartUploads
to delete partial uploads and free the allocated storage space for the parts you uploaded. 使用listMultipartUploads
查找废弃的上载,并使用abortMultipartUploads
删除部分上载并释放为上载的零件分配的存储空间。 Otherwise, uploads you don't complete will linger indefinitely and you'll be billed for storage of the parts. 否则,您未完成的上传将无限期地徘徊,并且您将需要为存储部分付费。 Also, you can create a bucket lifecycle policy to dispose of them automatically after so many days -- almost always a good idea. 此外,您可以创建存储桶生命周期策略,以便在这么多天后自动处理它们-几乎总是一个好主意。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.