我正在尝试使用JS SDK从浏览器上传多部分s3。我对createMultipartUpload没有任何问题,但我没有从uploadPart返回任何数据。我无法调用completeMultipartUpload,因为我没有收到任何eTags。我只得到对象的$ response部分,表示200状态,并且我传递的所有参数都已定义,并且正确的数据类型。虽然我不知道他们是否会去一个我无法访问的特殊“部分”地方,但我看不到我的桶里有任何部件。
这是我的代码:
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实例看起来像这样:
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函数如下所示:
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);
}
我回来的响应对象看起来像这样:
(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)
有什么想法吗?这是在React中,我的测试文件是9.xx MB。我也试过回调,一次上传一个部分,并得到同样的东西。
答案 0 :(得分:1)
在跨源环境中,您需要在您的存储桶的CORS配置中使用此功能:
<ExposeHeader>ETag</ExposeHeader>
ExposeHeader
- 标识客户将能够从其应用程序访问的响应标头(例如,来自JavaScript XMLHttpRequest对象)。&#34;
为了澄清这里的内容,CORS并不是一种访问限制机制 - 它是一种机制,可以让浏览器做一些其他假设可能不属于用户的事情的权限我想要发生。它告诉浏览器授予JavaScript权限并查看不允许的其他内容。
来自Mozilla CORS文档:
默认情况下,只显示6个简单响应标头:
Cache-Control
Content-Language
Content-Type
Expires
Last-Modified
Pragma
如果您希望客户端能够访问其他标头,则必须使用
Access-Control-Expose-Headers
标头列出它们。https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers
在S3中,您设置Access-Control-Expose-Headers
响应标头的方式是配置<ExposeHeaders>
(上方)。否则,JavaScript无法看到它们。
我无法看到我的水桶中的任何部件,虽然我不知道他们是否会去一个特殊的部件&#34;我无法访问的地方。
他们是。使用listMultipartUploads
查找已放弃的上传内容,使用abortMultipartUploads
删除部分上传内容,并为您上传的部分释放已分配的存储空间。否则,您无法完成的上传将无限期地停留,并且您需要为存储部件付费。此外,您可以创建bucket lifecycle policy以在这么多天后自动处理它们 - 几乎总是一个好主意。