S3 中存在一个已知问题,如果系统出于某种原因时钟不同步,则上传会失败并出现
RequestTimeTooSkewed
错误。
当服务器触发此问题时,有很多解决方案(基本上修复服务器时钟),但是当我的应用程序用户的浏览器触发此问题时,我该怎么办?
即使将
correctClockSkew
设置为 true
也无法解决问题。
AWS.config.update({
correctClockSkew: true,
...
});
这是浏览器中 JavaScript 的一个潜在解决方案,用于纠正客户端时钟偏差。您的客户端向 S3 存储桶发送 HEAD 请求(因此需要权限,或者您使用公共存储桶,并且您需要存储桶上的 CORS 来公开数据标头):
correctClockSkew = (Bucket) => {
const s3 = new AWS.S3();
// Head the bucket to get a Date response. The 'date' header
// will need to be exposed in S3 CORS configuration.
s3.headBucket({ Bucket }, (err, data) => {
if (err) {
console.log('headBucket error:', err);
} else {
console.log('headBucket data:', JSON.stringify(data));
console.log('headBucket headers:', JSON.stringify(this.httpResponse.headers));
if (this.httpResponse.headers.date) {
const date = Date.parse(this.httpResponse.headers.date);
console.log('headers date:', date);
AWS.config.systemClockOffset = new Date() - date;
console.log('clock offset:', AWS.config.systemClockOffset);
// Can now safely generate presigned urls
}
}
});
};
这是从 aws-js-s3-explorer 项目借来的。
另一种选择是等待重试事件(借自此评论):
AWS.events.on('retry', function (response: any) {
if (response.error.name === 'RequestTimeTooSkewed') {
var serverTime = Date.parse(response.httpResponse.headers['date']);
var timeNow = new Date().getTime();
AWS.config.systemClockOffset = Math.abs(timeNow - serverTime);
response.error.retryable = true;
}
});
对于我自己来说,直到我在 AWS S3 中公开了“Date”CORS 标头之后,
correctClockSkew: true
才起作用。然后就完美运行了。