处理HTTPS页面中的HTTP内容

El *_*obo 86 https image http

我们有一个完全通过HTTPS访问的站点,但有时会显示外部内容,即HTTP(主要来自RSS提要的图像).绝大多数用户也坚持使用IE6.

我理想的是喜欢做以下两种情况

  • 防止关于不安全内容的IE警告消息(以便我可以显示较少侵入性的内容,例如通过使用默认图标替换图像,如下所示)
  • 向用户展示一些有用的东西,代替他们无法看到的图像; 如果有一些JS,我可以找出哪些图像没有加载,并用我们的图像替换它们,这将是伟大的.

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

最糟糕的情况是我在导入时解析RSS源,抓取图像将它们存储在本地,以便用户可以通过这种方式访问​​它们,但似乎很难获得相当大的收益.

Sri*_*nan 146

你最糟糕的情况并不像你想象的那么糟糕.

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

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

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

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

最后,hash参数用于安全性; 您只希望您的servlet为您构建的URL提供图像.因此,在创建URL时,计算md5(image_url + secret_key)并将其作为哈希参数附加.在您提供请求之前,请重新计算哈希值并将其与传递给您的哈希值进行比较.由于secret_key只为您所知,因此没有其他人可以构建有效的URL.

如果您使用java进行开发,那么Servlet只需几行代码.您应该能够在任何其他后端技术上移植以下代码.

/*
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);
    }    
}
Run Code Online (Sandbox Code Playgroud)

  • 这种方法唯一严重的缺点是您通过自己的系统路由所有外部资源.这不仅是一种责任,而且还会变得相当昂贵. (32认同)
  • NodeJS的解决方案是什么? (2认同)

nul*_*ble 13

如果您正在寻找通过HTTPS加载图像的快速解决方案,那么https://images.weserv.nl/上的免费反向代理服务可能会让您感兴趣.这正是我想要的.

如果您正在寻找付费解决方案,我之前使用的Cloudinary.com也运行良好,但在我看来,这个任务太昂贵了.

  • @JackNicholson我已经在相对较重的负荷下使用它2年了.效果很好!感谢两位开发者. (5认同)