【问题标题】:Make HttpURLConnection load web pages with images使 HttpURLConnection 加载带有图像的网页
【发布时间】:2011-06-08 14:44:51
【问题描述】:

目前我正在使用 HttpURLConnection 加载远程网页并呈现给我的客户(使用 InputStream 到 HttpResponse 的 outputStream 传输),它可以正确加载 html 但会跳过图像,如何解决?

谢谢

【问题讨论】:

    标签: java servlets httpurlconnection


    【解决方案1】:

    您需要以这种方式操作 HTML,以便 Intranet 域上的所有资源 URL 也被代理。例如。以下所有 HTML 中的资源引用

    <base href="http://intranet.com/" />
    <script src="http://intranet.com/script.js"></script>
    <link href="http://intranet.com/style.css" />
    <img src="http://intranet.com/image.png" />
    <a href="http://intranet.com/page.html">link</a>
    

    应该以这种方式在 HTML 中进行更改,以便它们通过您的代理 servlet,例如

    <base href="http://example.com/proxy/" />
    <script src="http://example.com/proxy/script.js"></script>
    <link href="http://example.com/proxy/style.css" />
    <img src="http://example.com/proxy/image.png" />
    <a href="http://example.com/proxy/page.html">link</a>
    

    Jsoup 这样的HTML 解析器在这方面非常有帮助。您可以在您的代理 servlet 中执行以下操作,我假设它映射到 /proxy/* 的 URL 模式。

    String intranetURL = "http://intranet.com";
    String internetURL = "http://example.com/proxy";
    
    if (request.getRequestURI().endsWith(".html")) { // A HTML page is requested.
        Document document = Jsoup.connect(intranetURL + request.getPathInfo()).get();
    
        for (Element element : document.select("[href]")) {
            element.attr("href", element.absUrl("href").replaceFirst(intranetURL, internetURL));
        }
    
        for (Element element : document.select("[src]")) {
            element.attr("src", element.absUrl("src").replaceFirst(intranetURL, internetURL));
        }
    
        response.setContentType("text/html;charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
        resposne.getWriter().write(document.html());
    }
    else { // Other resources like images, etc.
        URLConnection connection = new URL(intranetURL + request.getPathInfo()).openConnection();
    
        for (Map.Entry<String, List<String>> header : connection.getHeaderFields().entrySet()) {
            for (String value : header.getValue()) {
                response.addHeader(header.getKey(), value);
            }
        }
    
        InputStream input = connection.getInputStream();
        OutputStream output = response.getOutputStream();
        // Now just copy input to output.
    }
    

    【讨论】:

    • 是的,这真的很有意义......奇怪的是没有工具可以开箱即用
    【解决方案2】:

    您必须为每张图片单独提出请求。这也是浏览器所做的。

    【讨论】:

    • Bozho,这对他没有帮助(我的意思是图像)...因为图像源也必须重定向。
    • 我认为 HtmlUnit 可以从网页中提取图像 url 并让您对每个图像发出新的请求。
    • 这很清楚,但据我了解其意图,OP 希望客户能够请求它们。为此,他们必须解析 html 并对所述图像提出专门的请求。这不是一件容易的事。
    • 如果这些请求必须来自客户端,我不确定 HtmlUnit 有什么用处。
    • 对不起,我没有得到他代表客户加载页面的场景。
    猜你喜欢
    • 1970-01-01
    • 2019-11-25
    • 1970-01-01
    • 2012-11-29
    • 1970-01-01
    • 1970-01-01
    • 2016-12-02
    • 2010-11-01
    • 1970-01-01
    相关资源
    最近更新 更多