从URL获取图像并保存在服务器和/或表(ImageField)上

时间:2013-09-20 16:22:03

标签: python django image imagefield

我没有看到太多关于此的文档。我正在尝试从URL上传到服务器上的图像。理想情况下,我想让事情变得简单,但我有两个想法,即使用ImageField是将文件存储在服务器上并将其显示为静态文件的最佳方式还是更简单。我没有上传任何文件,所以我需要将它们取出来。在尝试重新发明轮子之前,有人能建议任何合适的代码示例吗?

如果网址为http://www.xyx.com/image.jpg,我想将该图片下载到服务器,重命名后将其放入合适的位置。我的问题很笼统,因为我正在寻找人们已经做过的事例。到目前为止,我只看到有关上传图像的示例,但这不适用。这应该是一个简单的案例,我正在寻找一个可能有帮助的规范示例。

这是用于从用户上传图片:Django: Image Upload to the Server

那里有没有任何例子可以处理在服务器和/或ImageField上获取和存储图像和存储的过程。

1 个答案:

答案 0 :(得分:2)

好吧,只需获取图像并将其存储到文件中即可:

import urllib2
with open('/path/to/storage/' + make_a_unique_name(), 'w') as f:
    f.write(urllib2.urlopen(your_url).read())

然后,您需要配置Web服务器以提供该目录中的文件。

但这带来了安全风险

恶意用户可能会出现并输入无处指向的网址。或者指向他们自己的邪恶服务器,它接受你的连接但从不响应。这将是典型的denial of service攻击。

一个天真的修复可能是:

urllib2.urlopen(your_url, timeout=5)

然后对手可以构建一个接受连接的服务器,并且每秒无限期地写出一行,永不停止。 timeout不包括此内容。

因此,正确的解决方案是运行a task queue,同时运行timeouts,以及精心选择的工作人员数量,这些都完全独立于面向Web的流程。

另一种攻击是将您的服务器指向私有的。举例来说,假设您有一个在端口8000上运行的内部管理站点,并且无法访问到外部世界,但它 可访问到你自己的过程。然后我可以输入http://localhost:8000/path/to/secret/stats.png并查看所有有价值的秘密图表,甚至可以修改某些内容。这被称为server-side request forgery或SSRF,并且防御并非易事。您可以尝试解析URL并根据黑名单检查主机名,或明确解析主机名并确保它不指向任何机器或网络(包括127.0.0.0/8)。

然后,当然,存在验证您收到的文件实际上是图像而不是HTML文件或Windows可执行文件的问题。但这对于上传方案也很常见。