处理 HTTPS 页面中的 HTTP 内容 [英] Dealing with HTTP content in HTTPS pages

查看:37
本文介绍了处理 HTTPS 页面中的 HTTP 内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个完全通过 HTTPS 访问的网站,但有时会显示 外部内容,即 HTTP(主要来自 RSS 源的图像).我们的绝大多数用户还停留在 IE6 上.

We have a site which is accessed entirely over HTTPS, but sometimes display external content which is HTTP (images from RSS feeds, mainly). The vast majority of our users are also stuck on IE6.

我希望同时执行以下两项操作

I would ideally like to do both of the following

  • 防止出现关于不安全内容的 IE 警告消息(这样我就可以显示一个不那么具有侵入性的消息,例如,将图像替换为如下所示的默认图标)
  • 向用户展示一些有用的东西来代替他们看不到的图片;如果有一些 JS,我可以运行以找出哪些图像尚未加载并用我们的图像替换它们,那就太好了.

我怀疑第一个目标根本不可能,但第二个可能就足够了.

I suspect that the first aim is simply not possible, but the second may be sufficient.

最糟糕的情况是,我在导入 RSS 提要时解析它们,抓取图像将它们存储在本地,以便用户可以通过这种方式访问​​它们,但这似乎很痛苦,但收益却很少.

A worst case scenario is that I parse the RSS feeds when we import them, grab the images store them locally so that the users can access them that way, but it seems like a lot of pain for reasonably little gain.

推荐答案

最坏的情况并没有你想象的那么糟糕.

Your worst case scenario isn't as bad as you think.

您已经在解析 RSS 提要,因此您已经有了图片 URL.假设您有一个类似于 http://otherdomain.com/someimage.jpg 的图像 URL.您将此 URL 重写为 https://mydomain.com/imageserver?url=http://otherdomain.com/someimage.jpg&hash=abcdeafad.这样,浏览器总是通过 https 发出请求,这样你就摆脱了问题.

You are already parsing the RSS feed, so you already have the image URLs. Say you have an image URL like http://otherdomain.com/someimage.jpg. You rewrite this URL as https://mydomain.com/imageserver?url=http://otherdomain.com/someimage.jpg&hash=abcdeafad. This way, the browser always makes request over https, so you get rid of the problems.

下一部分 - 创建执行以下操作的代理页面或 servlet -

The next part - create a proxy page or servlet that does the following -

  1. 从查询字符串中读取 url 参数,并验证哈希
  2. 从服务器下载图像,并将其代理回浏览器
  3. 可选地,将图像缓存在磁盘上

这个解决方案有一些优点.您不必在创建 html 时下载图像.您不必在本地存储图像.此外,你是无国籍的;url 包含提供图像所需的所有信息.

This solution has some advantages. You don't have to download the image at the time of creating the html. You don't have to store the images locally. Also, you are stateless; the url contains all the information necessary to serve the image.

最后,hash参数是为了安全;您只希望您的 servlet 为您构建的 url 提供图像.因此,当您创建 url 时,计算 md5(image_url + secret_key) 并将其附加为哈希参数.在您处理请求之前,重新计算散列并将其与传递给您的内容进行比较.由于 secret_key 只有您自己知道,其他人无法构建有效的 url.

Finally, the hash parameter is for security; you only want your servlet to serve images for urls you have constructed. So, when you create the url, compute md5(image_url + secret_key) and append it as the hash parameter. Before you serve the request, recompute the hash and compare it to what was passed to you. Since the secret_key is only known to you, nobody else can construct valid urls.

如果你是用 java 开发的,Servlet 只是几行代码.您应该能够将以下代码移植到任何其他后端技术上.

If you are developing in java, the Servlet is just a few lines of code. You should be able to port the code below on any other back-end technology.

/*
targetURL is the url you get from RSS feeds
request and response are wrt to the browser
Assumes you have commons-io in your classpath
*/

protected void proxyResponse (String targetURL, HttpServletRequest request,
 HttpServletResponse response) throws IOException {
    GetMethod get = new GetMethod(targetURL);
    get.setFollowRedirects(true);    
    /*
     * Proxy the request headers from the browser to the target server
     */
    Enumeration headers = request.getHeaderNames();
    while(headers!=null && headers.hasMoreElements())
    {
        String headerName = (String)headers.nextElement();

        String headerValue = request.getHeader(headerName);

        if(headerValue != null)
        {
            get.addRequestHeader(headerName, headerValue);
        }            
    }        

    /*Make a request to the target server*/
    m_httpClient.executeMethod(get);
    /*
     * Set the status code
     */
    response.setStatus(get.getStatusCode());

    /*
     * proxy the response headers to the browser
     */
    Header responseHeaders[] = get.getResponseHeaders();
    for(int i=0; i<responseHeaders.length; i++)
    {
        String headerName = responseHeaders[i].getName();
        String headerValue = responseHeaders[i].getValue();

        if(headerValue != null)
        {
            response.addHeader(headerName, headerValue);
        }
    }

    /*
     * Proxy the response body to the browser
     */
    InputStream in = get.getResponseBodyAsStream();
    OutputStream out = response.getOutputStream();

    /*
     * If the server sends a 204 not-modified response, the InputStream will be null.
     */
    if (in !=null) {
        IOUtils.copy(in, out);
    }    
}

这篇关于处理 HTTPS 页面中的 HTTP 内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆