Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何修改web2py下载函数返回;“304未修改”;如果文件没有更改?_Python_Google App Engine_Web2py - Fatal编程技术网

Python 如何修改web2py下载函数返回;“304未修改”;如果文件没有更改?

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

在我的例子中,我有一个数据库,其中的文档缩略图显示在概览页面上。每次浏览器访问站点时,都会再次下载所有缩略图,因此下载功能会再次加载数据库中的所有图像。由于我在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)

首先,如果图像是公开的,并且不需要身份验证才能查看,那么您可以将它们存储在/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的源,对我来说,它似乎是t
stream\u file\u或\u 304\u或\u 206
仅当流是文件系统上的str->a文件时才执行。这在某种程度上是有意义的,因为否则系统在上次修改文件时没有信息。解决方法是在表中添加一个add'last modified'字段,并在调用response.stream和之前手动检查它如果last modified等于数据库值,则引发304异常。但由于这也需要数据库查询,因此无法解决我的问题。我将更新您对我的工作解决方案的回答。您能否提供指向Google高性能图像API文档的链接?