1

就我而言,我有一个数据库,其中包含显示在概览页面上的文档缩略图。每次浏览器访问该站点时,都会再次下载所有缩略图,因此下载功能会再次加载数据库中的所有图像。因为我在 GAE 上运行,所以我的数据库读取量很大。

我尝试通过设置启用客户端站点缓存:

@auth.requires_login()
def download():
  response.headers['Cache-Control'] = None
  response.headers['Pragma'] = None
  response.headers['Expires'] = None
  return response.download(request, db)

我还读到 response.stream 可能会有所帮助,但 web2py 书说:

如上所述,response.download 应该用于检索通过上传字段存储的文件。response.stream 可用于其他情况,例如返回一个临时文件或控制器创建的 StringIO 对象。

- 编辑 -

我启用了客户端缓存:

session.forget() #important
expire_time = datetime.timedelta(days=2)

response.headers['Cache-Control'] = 'private, max-age%d'%(60*60*24*2)
response.headers['Pragma'] = None
response.headers['Expires'] = (request.utcnow + expire_time).strftime("%a, %d %b %Y %H:%M:%S GMT")
response.headers['Content-Disposition'] = \
      'attachment;filename=' + filename + ';'

return response.stream(stream, filename=filename)
4

2 回答 2

2

首先,如果图像是公开可用的并且不需要验证即可查看,那么您可以将它们存储在 /static 文件夹中,然后将它们作为静态文件提供,而不是将它们存储在 /uploads 文件夹中。在这种情况下,将自动为客户端缓存设置标头(它也将更快、更高效)。

其次,您可以使用response.stream()流式传输上传的文件,但它不会自动识别文件所在的文件夹,也不会从编码的文件名中解码原始文件名并将其添加到 Content-Disposition 标头(您不需要在无论如何,这种情况是因为您正在显示图像而不是下载它们)。因此,只要您将完整的文件路径传递给response.stream(),您应该能够在这种情况下使用它,并且它将适当地设置响应标头以进行缓存。

最后,如果您想直接设置响应标头,则类似于:

import os
import time
modified = os.stat(file)[stat.ST_MTIME]
mtime = time.strftime('%a, %d %b %Y %H:%M:%S GMT', time.gmtime(modified))
response.headers['Last-Modified'] = mtime
response.headers['Pragma'] = 'cache'
response.headers['Cache-Control'] = 'private'
于 2013-01-25T05:56:44.980 回答
0

如果您提供图片,为什么不使用 Google 高性能图片服务。使用此 API (get_serving_url),Google 将为您提供图像。您不需要处理程序!它速度很快,您可以调整大小,而且只需要一些带宽。

但这仅适用于图像。这是我的一些代码,用于从 blobstore 提供 CSS,包括 304。

class DynCSS(blobstore_handlers.BlobstoreDownloadHandler):

    def get(self, resource):                                        

        (key, _, _) = resource.rpartition('.')
        self.response.headers[str('ETag')] = str(key)
        if 'If-None-Match' in self.request.headers:
            etags = [x.strip()
                     for x in self.request.headers[str('If-None-Match')].split(',')]
            if key in etags:
                self.response.set_status(304) # optimize traffic 304
                return
        blob_info = blobstore.BlobInfo.get(key) 
        self.send_blob(blob_info, save_as=True)

resource 参数是一个添加了 .css 的 blob_key。我使用 unicode 文字。

高性能图像服务使用:get_serving_url https://developers.google.com/appengine/docs/python/images/functions

例子 :

entity.serving_url = images.get_serving_url(entity.blob_key, size=None, secure_url=True)

如何使用 :

  • 将您的图片上传到您的 blobstore
  • 将带有图像文件名的 blob_key 保存在数据存储中
  • 创建一个 get_serving_url。您只需创建一次。
  • 在您的模板 img 标签中使用服务网址。

serving_url 看起来像这样:https ://lh6.ggpht.com/lOghqU2JrYk8M-Aoio8WjMM6mstgZcTP0VzJk79HteVLhnwZy0kqbgVGQZYP8YsoqVNzsu0EBysX16qMJe7H2BsOAr4j=s70

于 2013-01-25T09:58:27.323 回答