const moment = require('moment');
const tk = require("timekeeper");
function url4download(awsPath, awsKey) {
function getFrozenDate() {
return moment().startOf('week').toDate();
}
// Paramters for getSignedUrl function
const params = {
// Ref: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html
// Ref: https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html
Bucket: awsBucket,
Key: `${awsPath}/${awsKey}`,
// 604800 == 7 days
ResponseCacheControl: `public, max-age=604800, immutable`,
Expires: 604800, // 7 days is max
};
const url = tk.withFreeze(getFrozenDate(), () => {
return S3.getSignedUrl('getObject', params);
});
return url;
}
字符串
**注意:**使用moment().toDate()作为计时器需要一个Native Date Object。
更坚韧的问题是使用knox库,我的答案是使用aws官方库。
// This is how the AWS & S3 is initiliased.
const AWS = require('aws-sdk');
const S3 = new AWS.S3({
accessKeyId: awsAccessId,
secretAccessKey: awsSecretKey,
region: 'ap-south-1',
apiVersion: '2006-03-01',
signatureVersion: 'v4',
});
5条答案
按热度按时间busg9geu1#
我正在使用Java AmazonS3客户端,但过程应该是一样的。
有一种策略可以用来处理这种情况。
您可以使用固定的日期时间作为到期日期。我把这个日期设定为明天下午12点。
现在,每次您生成一个URL,它将在一天中保持不变,直到00:00。这样,浏览器缓存可以在某种程度上使用。
wa7juj8i2#
扩展@semir-deljić答案。
每次我们调用
getSignedUrl
函数,它都会生成新的URL。这将导致即使存在Cache Control
标头也无法缓存图像。因此,我们使用计时器库来冻结时间。现在,当函数被调用时,它认为时间没有过去,并返回相同的URL。
字符串
**注意:**使用
moment().toDate()
作为计时器需要一个Native Date Object。更坚韧的问题是使用
knox
库,我的答案是使用aws官方库。型
灵感来源:https://advancedweb.hu/cacheable-s3-signed-urls/
pengsaosao3#
如果您将CloudFront与S3一起使用,则可以使用自定义策略,如果您将每个URL限制为用户的IP和合理的长超时,则意味着当他们再次请求相同的内容时,他们将获得相同的URL,因此他们的浏览器可以缓存内容,但URL将不适用于其他人(在不同的IP上)。
(see:http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-creating-signed-url-custom-policy.html)
ghhkc1vu4#
当计算签名URL时,您可以将'signingDate'设置为过去的固定时刻,例如然后从那一刻开始计算到期日。不要忘记使用UTC和时区。
字符串
qacovj5a5#
您可以使用window.caches创建自己的浏览器缓存逻辑
参见this other stackoverflow question中的示例