处理HTTPS页面中的HTTP内容
我们有一个完全通过HTTPS访问的网站,但有时会显示外部内容 ,即HTTP(主要来自RSS源的图像)。 绝大多数用户也被困在IE6上。
我理想喜欢做以下两个
- 防止有关不安全内容的IE警告消息(这样我可以显示一个不太安全的内容,例如,用下面的默认图标replace图像)
- 给用户提供一些有用的信息,以代替他们无法看到的图像; 如果有一些JS我可以运行找出哪些图像没有被加载,并用我们的图像取而代之,这将是伟大的。
我怀疑第一个目标根本不可能,但第二个目标可能就足够了。
最糟糕的情况是,我们在导入时会parsingRSS提要,抓取图像存储在本地,以便用户可以以这种方式访问它们,但是看起来像是一个很小的收获。
你最糟糕的情况并不像你想象的那么糟糕。
您已经parsing了RSS提要,因此您已经有了图片url。 假设你有像someimage.jpg
这样的图片url。 您将此URL重写为https://mydomain.com/imageserver?url=someimage.jpg&hash=abcdeafad
。 这样,浏览器总是通过https请求,所以你摆脱了问题。
接下来的部分 – 创build一个代理页面或servlet来完成以下任务 –
- 从查询string中读取url参数,并validation散列
- 从服务器下载图像,并将其代理回浏览器
- (可选)将图像caching在磁盘上
这个解决scheme有一些优点。 您不必在创buildhtml时下载图像。 您不必在本地存储图像。 另外,你是无国籍的; 该url包含了提供图片所需的所有信息。
最后,散列参数是为了安全; 你只希望你的servlet为你构build的url提供图片。 所以,当你创buildurl时,计算md5(image_url + secret_key)
并将其附加为散列参数。 在提供请求之前,请重新计算散列并将其与传递给您的内容进行比较。 由于秘密密钥只有你自己知道,没有其他人可以构build有效的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); } }
我不知道这是否适合你在做什么,但作为一个快速解决scheme,我会将http内容“包装”到https脚本中。 例如,在通过https提供的页面上,我将引入一个iframe来replace您的rss提要,并在iframe的src attr中放置一个服务器上的脚本url,以捕获feed并输出html。 该脚本通过http读取Feed并通过https输出(因此“包装”)
只是一个想法
如果您正在寻找通过HTTPS加载图片的快速解决scheme,那么https://images.weserv.nl/上的免费反向代理服务可能会让您感兴趣。; 这正是我所期待的。
如果你正在寻找一个付费的解决scheme,我以前曾经使用过Cloudinary.com,这个工作也很好,但是对于这个任务来说太贵了。
关于你的第二个要求 – 你可能会使用onerror事件,即。 <img onerror="some javascript;"...
更新:
你也可以尝试迭代DOM中的document.images
。 有一个complete
布尔属性,您可能可以使用。 我不确定这是否合适,但可能值得调查。
在https上最好只有http内容
有时候就像在Facebook应用程序中,我们不能在安全页面中存在不安全的内容。 也不能使当地的内容。 例如一个应用程序,它将加载在iFrame中不是一个简单的内容,我们不能使它在本地。
我认为我们不应该在https中加载http内容,也不应该将https页面回退到http版本以防止错误对话框。
确保用户安全的唯一方法是使用所有内容的https版本, http://developers.facebook.com/blog/post/499/
最好的方式为我工作
<img src="/path/image.png" />// this work only online or <img src="../../path/image.png" /> // this work both or asign variable <?php $base_url = ''; if($_SERVER['HTTP_HOST'] == 'localhost') { $base_url = 'localpath'; } ?> <img src="<?php echo $base_url;?>/path/image.png" />
简单地说:不要做。 HTTPS页面中的Http内容本质上是不安全的。 点。 这就是为什么IE显示警告。 摆脱警告是一个愚蠢的hogwash方法。
相反,HTTPS页面应该只有 HTTPS内容。 确保内容可以通过HTTPS加载,如果页面通过https加载,则通过https引用。 对于外部内容,这将意味着加载和caching元素在本地,以便他们可以通过HTTPS确定。 不幸的是,没有办法。
警告是有原因的。 认真。 花5分钟的时间思考如何用自定义内容接pipe一个https显示的页面 – 你会感到惊讶。
我意识到这是一个旧的线程,但一个选项是从图像URL中删除http:部分,以便' http://some/image.jpg '变成'//some/image.jpg'。 这也将与CDN一起工作