我允许我的用户上传头像图片(谷歌应用引擎,java)。我不知道他们上传时的图像类型。我只是在提交表格中存储他们给我的任何内容。我在这里关注这个例子:
http://code.google.com/appengine/docs/python/images/usingimages.html
有没有办法在存储之前检查它是什么图像类型?例如,如果他们提交了一个文本文件,我不想接受它。
另外,如何在返回图像时更改内容类型?我需要知道它是什么图像类型,才能正确设置内容类型?:
resp.setHeader("Content-Type", "image/jpg");
我正在使用java,
由于
答案 0 :(得分:3)
通常,如果您使用的是基于浏览器的文件上传,则表单数据将包含文件名和从文件扩展名推断的内容类型。但是,这并不能保证用户没有上传具有误导性扩展名的文件。要验证内容类型,您可以使用Images service:
Image img = ImagesServiceFactory.makeImage(uploadedBytes);
String contentType = "image/" + img.getFormat().toString().toLowerCase();
支持的类型有BMP,GIF,ICO,JPEG,PNG和TIFF。其他任何事都应该失败。
这可能不言而喻,但您应该仅在上传时检查内容类型,然后将其与图像一起存储;不要调用图像服务来查找每个下载请求的类型。
答案 1 :(得分:1)
如果根据文件扩展名检查内容类型,则可以使用ServletContext#getMimeType()
。
String mimeType = getServletContext().getMimeType(filename);
if (mimeType.startsWith("image")) {
// It's an image.
}
默认的mime类型在相关servletcontainer的web.xml
中定义。例如Tomcat,它位于/conf/web.xml
。您可以在网络应用的/WEB-INF/web.xml
中扩展/覆盖它,如下所示:
<mime-mapping>
<extension>svg</extension>
<mime-type>image/svg-xml</mime-type>
</mime-mapping>
但这并不能阻止您通过更改文件扩展名来欺骗您的用户。如果您还要覆盖此内容,则还可以根据实际文件内容确定mime类型。你可以通过嗅探file headers来做到这一点。考虑使用第三方库来完成所有工作。我发现JMimeMagic对此很有用。您可以按如下方式使用它:
String mimeType = Magic.getMagicMatch(uploadedFile, false).getMimeType();
为了能够回传图像,你可以设置响应内容类型,结果为ServletContext#getMimeType()
(在上传过程中不要忘记确认这等于JMimeMagic返回的内容,对于案例这一点)。
response.setContentType(getServletContext().getMimeType(file.getName()));
答案 2 :(得分:0)
为什么不直接从文件名中获取扩展名,并使用它来确定它是什么类型的图像,并从中找出mime类型?
另一种方法是使用谷歌应用引擎图像处理API使用不同的文件类型打开您的图像,并检查哪一个不会导致错误。这将是CPU密集型但更可靠。