Python 如何修改web2py下载函数返回;“304未修改”;如果文件没有更改?
在我的例子中,我有一个数据库,其中的文档缩略图显示在概览页面上。每次浏览器访问站点时,都会再次下载所有缩略图,因此下载功能会再次加载数据库中的所有图像。由于我在GAE上运行,这会提高我的数据库读取量 我试图通过设置启用客户端站点缓存:Python 如何修改web2py下载函数返回;“304未修改”;如果文件没有更改?,python,google-app-engine,web2py,Python,Google App Engine,Web2py,在我的例子中,我有一个数据库,其中的文档缩略图显示在概览页面上。每次浏览器访问站点时,都会再次下载所有缩略图,因此下载功能会再次加载数据库中的所有图像。由于我在GAE上运行,这会提高我的数据库读取量 我试图通过设置启用客户端站点缓存: @auth.requires_login() def download(): response.headers['Cache-Control'] = None response.headers['Pragma'] = None response.hea
@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)
首先,如果图像是公开的,并且不需要身份验证才能查看,那么您可以将它们存储在/static文件夹中,而不是将它们存储在/uploads文件夹中,然后将它们作为静态文件使用。在这种情况下,将自动为客户端缓存设置头(这也将更快、更高效) 其次,您可以使用
response.stream()
对上载的文件进行流式传输,但它不会自动识别文件所在的文件夹,也不会从编码的文件名中解码原始文件名并将其添加到内容处置头(在本例中,您不需要它,因为您正在显示图像而不是下载它们)。因此,只要您将完整的文件路径传递到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'
如果您提供图像,为什么不使用谷歌高性能图像服务。使用此API(get_serving_url),谷歌将为您提供图像。您不需要处理程序!它速度快,可以调整大小,而且只需花费一些带宽 但这只适用于图像。下面是我的一些代码,用于从blobstore(包括304)提供CSS
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)
资源参数是一个添加了.css的blob_键,我使用unicode文本
高性能图像服务用途:获取\u服务\u url
例如:
entity.serving_url = images.get_serving_url(entity.blob_key, size=None, secure_url=True)
如何使用:
- 将图像上载到blobstore
- 在数据存储中使用图像文件名保存blob_密钥
- 创建一个get\u服务url。您只需创建一次
- 在模板img标记中使用服务URL
服务url如下所示:我无法将图像直接存储在静态文件夹中,因为:1.应用程序在Google App Engine上运行。2.文件需要身份验证。我将用你的第二个提议试试运气。我尝试了:
response.headers['Content-Type']='image/jpeg'
,response.headers['Pragma']='cache'
,response.headers['cache-Control']='private'
和返回response.stream(stream,filename=filename)
但是服务器没有响应304,我遗漏了什么?抱歉,忘了你提到你在GAE上。你也设置了上次修改的头吗?好的,我意识到的第一件事是我必须使用会话。忘记()
。否则(GAE或web2py?)由于当前的set Cookie
标头,将Expire
标头设置为当前时间。这是因为某些代理存在安全问题。是的,我以前也设置了上次修改的标头。我会在它工作时发布更多详细信息。我查看了response.stream的源,对我来说,它似乎是tstream\u file\u或\u 304\u或\u 206
仅当流是文件系统上的str->a文件时才执行。这在某种程度上是有意义的,因为否则系统在上次修改文件时没有信息。解决方法是在表中添加一个add'last modified'字段,并在调用response.stream和之前手动检查它如果last modified等于数据库值,则引发304异常。但由于这也需要数据库查询,因此无法解决我的问题。我将更新您对我的工作解决方案的回答。您能否提供指向Google高性能图像API文档的链接?