Sar*_*tra 19 nginx amazon-s3 fileserver node.js express
我有应用程序用户的照片是私人的.我将照片(缩略图也)存储在AWS s3中.网站中有一个页面,用户可以在其中查看他的照片(即缩略图).现在我的问题是如何提供这些文件.我评估的一些选项是:
我无法评估这两个选项中哪一个是更好的选择?我想尽可能多地将工作重定向到S3或cloudfront,但即使使用了singed url也会首先向我的服务器发出请求.我也想要缓存功能.
那么理想的做法是什么?有关这些方法的特定问题的答案?
Jon*_*Ong 20
我会从S3流式传输它.它非常简单,签名的URL要困难得多.只需确保在将图像上传到S3时设置content-type
和content-length
标题.
var aws = require('knox').createClient({
key: '',
secret: '',
bucket: ''
})
app.get('/image/:id', function (req, res, next) {
if (!req.user.is.authenticated) {
var err = new Error()
err.status = 403
next(err)
return
}
aws.get('/image/' + req.params.id)
.on('error', next)
.on('response', function (resp) {
if (resp.statusCode !== 200) {
var err = new Error()
err.status = 404
next(err)
return
}
res.setHeader('Content-Length', resp.headers['content-length'])
res.setHeader('Content-Type', resp.headers['content-type'])
// cache-control?
// etag?
// last-modified?
// expires?
if (req.fresh) {
res.statusCode = 304
res.end()
return
}
if (req.method === 'HEAD') {
res.statusCode = 200
res.end()
return
}
resp.pipe(res)
})
})
Run Code Online (Sandbox Code Playgroud)
如果您使用302 Found
浏览器将用户重定向到已签名的URL,则会根据其cache-control
标题缓存生成的图像,并且不会再次询问它.
为防止浏览器缓存已签名的URL本身,您应该发送正确的Cache-Control
标头:
Cache-Control: private, no-cache, no-store, must-revalidate
Run Code Online (Sandbox Code Playgroud)
因此,下次它会向原始网址发送请求,并将重定向到新签名的网址.
您可以knox
使用using signedUrl
方法生成签名的URL .
但是不要忘记为每个上传的图像设置正确的标题.我建议你使用两个Cache-Control
和Expires
标题,因为某些浏览器不支持Cache-Control
标题,并Expires
允许你只设置绝对过期时间.
使用第二个选项(通过您的应用程序流式传输图像),您可以更好地控制情况.例如,您将能够Expires
根据当前日期和时间为每个响应生成标头.
但速度怎么样?使用签名的URL有两个优点,可能会影响页面加载速度.
首先,您不会使服务器过载.如果快速生成签名的URL,因为您只是哈希您的AWS凭据.要通过服务器流式传输图像,您需要在页面加载期间保持大量额外连接.无论如何,除非您的服务器是硬加载的,否则它不会产生任何实际差异.
其次,浏览器在页面加载期间每个主机名只保留两个并行连接.因此,浏览器将在下载时保持并行解析图像网址.它还可以阻止从任何其他资源的下载下载图像.
无论如何,要绝对确定你应该运行一些基准测试.我的回答是基于我对HTTP规范的了解以及我在Web开发方面的经验,但我从未试图以自己的方式提供图像.直接从S3提供具有长缓存生命周期的公共图像可以提高页面速度,我相信如果您通过重定向进行,情况不会改变.
您应该记住,通过您的服务器流式传输图像将带来Amazon CloudFront的所有好处.但只要您直接从S3提供内容,两个选项都可以正常工作.
因此,在使用签名网址时,有两种情况应该加速您的网页:
如果您在每个页面上只有很少的图像并直接从S3提供它们,您可能根本不会看到任何差异.
我运行了一些测试,发现我对缓存有误.确实,浏览器会缓存重定向到的图像.但它将缓存的图像与重定向到的URL相关联,而不是与原始图像相关联.因此,当浏览器第二次加载页面时,它再次从服务器请求图像,而不是从缓存中获取图像.当然,如果服务器使用相同的重定向URL响应它第一次响应,浏览器将使用其缓存,但签名网址不是这种情况.
我发现强制浏览器缓存已签名的URL以及它收到的数据可以解决问题.但我不喜欢缓存无效重定向URL的想法.我的意思是,如果浏览器以某种方式错过图像,它将尝试使用缓存中的无效签名URL再次请求它.所以,我认为这不是一个选择.
如果CloudFront更快地提供图像或浏览器限制每个主机名的并行下载数量并不重要,使用浏览器缓存的优势超出了通过服务器管道图像的所有缺点.
看起来大多数社交网络通过将其实际网址隐藏在某些私有代理后面来解决私有图像的问题.因此,他们将所有内容存储在公共服务器上,但未经授权就无法获取私有映像的URL.当然,如果您在新标签页中打开私人图片并将网址发送给您的朋友,他也可以看到图片.所以,如果它不适合你,那么你最好使用Jonathan Ong的解决方案.
归档时间: |
|
查看次数: |
12280 次 |
最近记录: |