ImageIO.read() 返回 403 错误

Posted

技术标签:

【中文标题】ImageIO.read() 返回 403 错误【英文标题】:ImageIO.read() returns 403 error 【发布时间】:2013-04-17 08:45:19 【问题描述】:

我有以下代码:

public BufferedImage urlToImage(String imageUrl) throws MalformedURLException, IOException 
    URL url = new URL(imageUrl);
    BufferedImage image = ImageIO.read(url);
    return image;

这应该从给定的 URL 返回一个图像。

我用这两个随机选择的 URL 进行了测试:

https://www.google.co.ma/images/srpr/logo4w.png http://www.earthtimes.org/newsimage/osteoderms-storing-minerals-helped-huge-dinosaurs-survive_3011.jpg

第一个工作正常,但第二个给出 403 错误:

Caused by: java.io.IOException: Server returned HTTP response code: 403 for URL: http://www.earthtimes.org/newsimage/osteoderms-storing-minerals-helped-huge-dinosaurs-survive_3011.jpg
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1436)
at java.net.URL.openStream(URL.java:1010)
at javax.imageio.ImageIO.read(ImageIO.java:1367)

错误的原因可能是什么?谢谢。

【问题讨论】:

【参考方案1】:

ImageIO.read(URL) 方法使用几乎所有默认设置打开一个 URL 连接,包括 User-Agent 属性(将设置为您正在运行的 JVM 版本)。显然,您列出的网站需要更“标准”的 UA。使用直接 telnet 连接进行测试:

ImageIO.read(url)发送的请求:

GET /newsimage/osteoderms-storing-minerals-helped-huge-dinosaurs-survive_3011.jpg HTTP/1.1 用户代理:Java/1.7.0_17 主持人:www.earthtimes.org 接受:文本/html、图像/gif、图像/jpeg、*; q=.2, /; q=.2 连接:保持活动

响应码是 404(至少对我而言),返回默认的 text/html 页面。

“标准”浏览器发送的请求:

GET /newsimage/osteoderms-storing-minerals-helped-huge-dinosaurs-survive_3011.jpg HTTP/1.1 用户代理:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.65 Safari/537.31 主持人:www.earthtimes.org 接受:文本/html、图像/gif、图像/jpeg、*; q=.2, /; q=.2 连接:保持活动

响应码为200,带有图片数据。

以下简单修复会延长您的代码,但通过设置更“标准”的 UA 来解决问题:

final String urlStr = "http://www.earthtimes.org/newsimage/osteoderms-storing-minerals-helped-huge-dinosaurs-survive_3011.jpg";
final URL url = new URL(urlStr);
final HttpURLConnection connection = (HttpURLConnection) url
        .openConnection();
connection.setRequestProperty(
    "User-Agent",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.65 Safari/537.31");
final BufferedImage image = ImageIO.read(connection.getInputStream());

【讨论】:

非常感谢。一个附带问题:这是否意味着服务器不想提供非标准 UA 以防止其内容在标准用途之外被使用?还是仅仅因为服务器设置为默认行为? 实际上,大多数服务器实现默认不会将 UA 列入黑名单。这个特定网站的管理员很可能不遗余力地禁止 Java 代理。 我担心版权问题。所以我认为如果管理员将 Java 代理列入黑名单,这可能意味着他们的图像不能在浏览器之外使用。(在我的应用程序中,用户可以提供一个 URL 作为个人资料图像,我存储所述图像,因此如果 URL 不可用不再,个人资料图像仍然可用)。我不确定我是否必须阻止用户使用该图像,或者只是警告他们可能侵犯版权.. 我很确定版权法是适用的,无论网站是否接受一个特定的 UA 而不是另一个。但是 IANAL 所以绝对不能在这方面给出建议。

以上是关于ImageIO.read() 返回 403 错误的主要内容,如果未能解决你的问题,请参考以下文章

尝试使用 ImageIO.read(class.getResource(URL)) 加载图像,但 getResource 返回 null

使用 ImageIO.read 的问题

使用 nginx 返回自定义 403 错误页面

无法使用 ImageIO.read(文件文件)读取 JPEG 图像

Java压缩图片ImageIO.read()报错

ImageIO.read(getClass().getResource("imagepath")) 中 getclass() 的实际目的是啥 [重复]