2011-09-06 126 views
10

我正在使用Google App Engine Blobstore来存储一系列文件类型(PDF,XLS等),并试图找到上传文件的原始文件名 - 存储在blob_info中 - 可用于命名下载的文件,即用户在保存对话框中看到'some_file.pdf'而非'very_long_db_key.pdf'。使用Google App Engine下载的文件名Blobstore

我不能看到任何文档将允许这样的:

http://code.google.com/appengine/docs/python/blobstore/overview.html

我见过的其他职位的提示,你可以在blob_info使用这些信息来设置内容部署头。这是达到预期目标的最佳方法吗?

回答

11

send_blob函数中有一个可选的'save_as'参数。默认情况下,它被设置为False。将其设置为True将导致文件被视为附件(即它会触发“保存/打开”下载对话框),用户将看到正确的文件名。

例子:

class ServeHandler(blobstore_handlers.BlobstoreDownloadHandler): 
    def get(self, resource): 
     resource = str(urllib.unquote(resource)) 
     blob_info = blobstore.BlobInfo.get(resource) 
     self.send_blob(blob_info,save_as=True) 

也可以通过传递一个字符串覆盖的文件名:

self.send_blob(blob_info,save_as='my_file.txt') 

如果你想要一些内容(如PDF)打开,而不是拯救你可以使用CONTENT_TYPE来确定行为:

blob_info = blobstore.BlobInfo.get(resource) 
type = blob_info.content_type 
if type == 'application/pdf':  
    self.response.headers['Content-Type'] = type 
    self.send_blob(blob_info,save_as=False) 
else: 
    self.send_blob(blob_info,save_as=True) 
+0

只需添加 - 如果原始文件名包含双引号,则下载对话框将在引号字符后截断文件名。我已经通过转义blob文件名中的双引号来解决这个问题: 'self.send_blob(blob_info,save_as = blob_info.filename。替换(''','\\'''))' (这里有一个相关的讨论[here](http://stackoverflow.com/questions/93551/how-to-encode-the-filename-parameter -of-content-disposition-header-in-http)) –

0

是的,这是最好的方法;只需使用给定的Blobstore键查询BlobInfo对象并使用其属性即可。

1

另一个选项是将文件名追加到下载URL的末尾。例如:

/files/AMIfv95HJJY3F75v3lz2EeyvWIvGKxEcDagKtyDSgQSPWiMnE0C2iYTUxLZlFHs2XxnV_j1jdWmmKbSVwBj6lYT0-G_w5wENIdPKDULHqa8Q3E_uyeY1gFu02Iiw9xm523Rxk3LJnqHf9n8209t4sPEHhwVOKdDF2A/prezents-list.doc 

如果您使用的Jinja2的模板,你可以构建这样的URL是这样的:

<a href="/files/{{blob_info.key()}}/{{blob_info.filename}}">{{file.filename}}</a> 

,那么你应该相应地调整你的URL映射到这样的事情:

('/files/([^/]+)/?.*', DownloadHandler) 

如果在URL中有blob键,则可以忽略服务器端代码中的文件名。

这种方法的好处是,可以直接在浏览器中打开图像或PDF等内容类型,便于快速查看。其他内容类型将被保存到磁盘。

相关问题