关于img 403 forbidden的一些思考
网页中经常需要显示图片给用户看,对网站本身来说有的图片是从本地图片服务器来的,但是一旦数量多了以后,磁盘空间又是一个问题。
所以有时就希望显示其他网站的Image,直接把其他网站的图片显示在我的网站上。但并不是所有的外网Image 都能直接连接过来显示。
很多情况下网站开发人员就会遇到 403 forbidden的问题。比如想显示来自IMDB的一张图片
<img src="http://ia.media-imdb.com/images/M/MV5BMjIwMjYyNjk4Nl5BMl5BanBnXkFtZTcwNzA4NDYwMw@@._V1_UY317_CR12,0,214,317_AL_.jpg" height="350" width="200">
本地localhost Debug的时候完全可以显示,但是将网站部署到服务器后就会遇到这样的错误

奇怪的是通过浏览器访问图片的连接,图片就正常的显示了出来。
这又是为什么?其实Referer是由浏览器自动加上的,但是也有例外比如
1. 直接通过浏览器访问
2. 在web前段使用location.href 或者location.replace
3. 利用HTTPS等加密协议
这就是HotLinking 盗链问题, 可以通过配置网站Server 端来实现这种反盗链的行为。
为什么像IMDB这样的网站要做 Anti HotLinking反盗链的事情呢?
版权的问题是一方面。
另一方面可以称作Bandwidth Theft, 当用户访问IMDB页面的时候,IMDB需要Bandwidth传输数据,而Bandwidth 是网站的成本之一。
好比谁也不愿意陌生人偷偷的把电器插到你的插座,偷偷的用你的电,而你去负担所有的费用。
如何配置Server实现Anti HotLinking 呢?
以Asp.net MVC 为例
可以给Controller 添加ActionFilter 或者添加处理AntiHotLinking 的 IHttpHandler
核心都是UrlReferrer
HttpRequest 有个字段 UrlReferrer:

该字段表示哪个Url 通过像上面Img Src的方式访问了Server.
//访问者的域
var refDomain = Request.UrlReferrer.Host; //当前WebSite的域
var serverDomain = Request.Url.Host;
最后可以通过判断 是否来自同一个域 来决定Anti HotLinking的策略
或者可以通过在web.config 中配置URLRewrite来实现

<rewrite>
<rules>
<rule name="Anti HotLinking Rule for Image" enabled="true" stopProcessing="true">
<match url=".*\.(gif|jpg|png)$" />
<conditions>
<add input="{HTTP_REFERER}" negate="true" pattern="^$" />
<add input="{HTTP_REFERER}" negate="true" pattern="http://www.yourwebsite.com/.*" />
<add input="{HTTP_REFERER}" negate="true" pattern="http://yourwebsite.com/.*" />
</conditions>
<action type="Rewrite" url="/images/anti-hotlinking.png" />
</rule>
</rules>
</rewrite>

如果网站用户就是希望看到不能显示的图片或者视频呢?
这里给大家推荐一个Chrome 插件 Anti-Anti-HotLinking
安装后就能看到未能显示的图片。
对该插件我没有仔细研究,有可能是通过Download来解决Hotlinking 问题的,也有可能是通过Chrome劫持Request 修改UrlReferer实现的。
对网站开发人员有什么解决办法吗?
1. 将外网的Image在Server端下载 再转换成 base64 最后传输给img 标签。

public static string ImageToBase64(Stream imageStream, ImageFormat format)
{
using (System.Drawing.Image image = System.Drawing.Image.FromStream(imageStream))
{
using (MemoryStream stream = new MemoryStream())
{
image.Save(stream, format); var result = System.Convert.ToBase64String(stream.ToArray());
return result;
}
}
}

<img src="data:image/png;base64,这里存放转换成base64的字符串 />
2. 利用RefererKiller这个JavaScript插件 绕过UrlReferer
ReferrerKiller.imageHtml("fakeweb/fakeimage.png"); 返回能够显示的img的Html字符串
ReferrerKiller.imageHtml("fakeweb/fakeimage.png"); 返回能够显示的img的DOM节点
其实这两个函数是同一个东西,可以捡方便的用。
这种方式解决HotLinking问题其实原理很简单,在web中 比如<script src="differentDomain/fake.js"> </script>
加载js 是没有跨域访问的问题。
ReferrerKiller 就动态生成一个iframe,并在iframe内加入img标签。利用src加载的特性把代码放到src中,就可以去掉Referer。
所以ReferrerKiller.imageHtml返回的是一个能显示图片的iframe。
关于img 403 forbidden的一些思考的更多相关文章
- Apache2.4部署django出现403 Forbidden错误解决办法
前言:Apache2.4部署django出现403 Forbidden错误最好要结合apache中的错误日志来观察出现何种错误导致出现403错误 下午百度了一下午没找到解决办法,试了n种方法,简直坑爹 ...
- [Linux] Nginx networking 403 Forbidden 静态文件不允许查看
nginx 的 403 Forbidden errors 表示你在请求一个资源文件但是nginx不允许你查看. 403 Forbidden 只是一个HTTP状态码,像404,200一样不是技术上的错误 ...
- [转]权限问题导致Nginx 403 Forbidden错误的解决方法
权限问题导致Nginx 403 Forbidden错误的解决方法 投稿:junjie 字体:[增加 减小] 类型:转载 时间:2014-08-22 这篇文章主要介绍了权限问题导致Nginx 403 F ...
- 一个奇葩常见的问题 nginx 403 forbidden错误
今天安装dedecms,配置Nginx,然后生成一键生成静态页面,然后就没有然后了,所有栏目页面都显示nginx 403 forbidden. 一般来说nginx 的 403 Forbidden er ...
- Nginx报错403 forbidden (13: Permission denied)的解决办法
由于开发需要,在本地环境中配置了LNMP环境,使用的是Centos 6.5 的yum安装,安装一切正常,但是由于默认网站文件夹比较奇葩,于是把网站文件用mv命令移动到了新的目录,并相应修改了配置文件, ...
- svn 403 Forbidden
用svn client的时候出现这么一个问题,客户端能正常check out,但是在check in(commit,mkdir等)的时候出错了: Server sent unexpected retu ...
- 403 Forbidden client denied by server configuration[apache2, linux]
在LAMP的配置过程中, 由于APACHE的版本问题, 即使是APACHE2和APACHE2.2也有很大的不同. 一般都有同一个环境配置多个虚拟网站的情况, 如果你在配置过程中遇到APACHE的不同版 ...
- nginx:403 forbidden 二种原因
出现403 forbidden的两种原因:1.是缺少索引文件(index.html/inde.php):2.是权限问题 一.缺少索引文件index.html/inde.php 比如下面的配置: ser ...
- urllib.error.HTTPError: HTTP Error 403: Forbidden
问题: urllib.request.urlopen() 方法经常会被用来打开一个网页的源代码,然后会去分析这个页面源代码,但是对于有的网站使用这种方法时会抛出"HTTP Error 40 ...
随机推荐
- Hadoop.2.x_集群初建
一.部分概念 1. 分布式:一个项目分为多个模块共同完成一个或多个任务,可部署在一个或多个机器 2. 集群:多个机器运行同一个项目或服务 3. 集群上可能运行着零个或多个分布式系统(比如Hadoop, ...
- "我爱记单词"测试报告兼功能展示
"我爱记单词"测试报告兼功能展示 前言: 我们大部分的测试都是一边开发一边完成的,这里给出软件开发基本完成后在使用时的一些测试例子. 一.背景介绍 我们的数据库中一共有10个表: ...
- 数据库分页和使用jstl标签替换分页的jsp代码
参考链接: http://www.mossle.com/docs/jsp/html/jsp-ch-15.html
- (转)实例分析:MySQL优化经验
[IT专家网独家]同时在线访问量继续增大,对于1G内存的服务器明显感觉到吃力,严重时甚至每天都会死机,或者时不时的服务器卡一下,这个问题曾经困扰了我半个多月.MySQL使用是很具伸缩性的算法,因此你通 ...
- LaTex 文本排版
一.对齐段落 \\ or \newline 另起一行,而不是另起一段 \\* 在强制断行后,还禁止分页 \newpage 另起一页 \linebreak[n] \nolinebreak[n] \pag ...
- 计划任务设置(/etc/crontab)
# /etc/crontab: system-wide crontab# Unlike any other crontab you don't have to run the `crontab'# c ...
- controlling the variance of request response times and not just worrying about maximizing queries per second
http://highscalability.com/blog/2010/11/4/facebook-at-13-million-queries-per-second-recommends-minim ...
- Java 内存区域划分
JVM的内存区域划分 学过C语言的朋友都知道C编译器在划分内存区域的时候经常将管理的区域划分为数据段和代码段,数据段包括堆.栈以及静态数据区.那么在Java语言当中,内存又是如何划分的 ...
- 在Win7系统中搭建Web服务器
局 域网Web服务器的主要功能是实现资源共享,同时借助于局域网服务器访问页面可有效的实现信息的同步.利用Web服务器,我们随时随地都可以将自己的信息 上传到服务器端,让其它关注你的用户能在第一时间内了 ...
- Android自动化测试工具——monkey简介及入门
记得第二家单位的安卓开发在上线前都用monkey压几个小时,确实也能发现些问题,崩溃率低了些,没测过的确实可以压一压 搜了下资料,monkey确实很简单,发现问题自己搜下是什么问题,别一发现什么就跑去 ...