我需要安全地向经过验证的用户提供图像(即它们不能作为静态文件提供)。我目前在我的Django项目中有以下Python视图,但它似乎效率低下。想要更好的方法吗?
def secureImage(request,imagePath):
response = HttpResponse(mimetype="image/png")
img = Image.open(imagePath)
img.save(response,'png')
return response
(图像从PIL导入。)
答案 0 :(得分:73)
嗯,有时需要重新编码(即在保持原始图像不变的情况下在图像上应用水印),但对于最简单的情况,您可以使用:
try:
with open(valid_image, "rb") as f:
return HttpResponse(f.read(), content_type="image/jpeg")
except IOError:
red = Image.new('RGBA', (1, 1), (255,0,0,0))
response = HttpResponse(content_type="image/jpeg")
red.save(response, "JPEG")
return response
答案 1 :(得分:1)
只是偶然发现了一些不好的建议(用于生产),并认为我会提到X-Sendfile,它可以与Apache和Nginx以及其他Web服务器一起使用。
https://pythonhosted.org/xsendfile/
像Nginx这样的现代Web服务器通常能够比它们所托管的任何Web应用程序更快,更高效,更可靠地提供文件。这些服务器还能够将它们托管的Web应用程序指定的磁盘上的文件发送到客户端。此功能通常称为X-Sendfile。
这个简单的库使任何WSGI应用程序都可以轻松使用X-Sendfile,这样它们就可以控制是否可以提供文件或提供文件时执行其他操作,而无需编写服务器特定的扩展名。用例包括:
将文档下载限制为经过身份验证的用户。
记录谁下载了文件。强制下载文件而不是 由浏览器呈现,或以不同于 通过设置Content-Disposition标头将其放在磁盘上。
基本思想是打开文件并将该句柄传递回Web服务器,然后Web服务器将字节返回给客户端,从而释放Python代码以处理下一个请求。这比上面的解决方案性能要好得多,因为另一端速度较慢的客户端可能会在您下载文件时挂起python线程。
这里是一个回购,它显示了如何针对各种Web服务器执行此操作,尽管它已经很老了,但它至少会让您对需要执行的操作有所了解。 https://github.com/johnsensible/django-sendfile
答案 2 :(得分:1)
利用FileResponse
一种更简洁的方式,这里我们不必担心 Content-Length
和 Content-Type
标头,当它们可以从 open()
的内容中猜出时自动设置。
from django.http import FileResponse
def send_file(response):
img = open('media/hello.jpg', 'rb')
response = FileResponse(img)
return response