apache服务器的url重写

来源:互联网 发布:mysql 5.6中文乱码 编辑:程序博客网 时间:2024/06/14 16:54

    据上一次写已经过去几天了,哎,最近状态不太好,代码和服务器都没有怎么搞,看了看小说玩了玩游戏,虚度了这几天,总的来说开学都现在的状态都不佳,也不知为什么,在这不多说了,先总结一下url重写的知识吧。

    url重写是一个很有用的知识,然而我却一直不知道…作为一个爱玩游戏的业余程序员来说真是伤不起,好多东西都是之后学的,具体我也忘了什么时候学的这些知识了,应该在买了云服务器之后吧,有了自己的服务器,用需求带动技术的进步,这个方法还是蛮适合我的…毕竟我这人比较懒。

    升华网的服务器用的是iis的代理,但是我的服务器之前是Nginx,现在换成apache了,在win平台还是apache好用些,我这里就以apache的为例了。

     url重写可以缩短url的长度,可以美化url,可以隐藏实际的网页地址 以及便于搜索引擎搜索和用户记忆。总之是一个特别实用的技术,下面我就总结一下~

     首先我们要打开apache (我如果不指明apache版本默认都是2代,因为2代和1代还是有很多区别的…) 的重写功能,打开httpd.conf文件搜索LoadModule rewrite_modulemodules/mod_rewrite.so 把前面的#号去掉,搜索AllowOverride 改成AllowOverride all。

    url的重写是基于正则表达式的,关于正则表达式我另外在写一篇文章吧。先来个例子

http://54sh.csu.edu.cn/readnews.jsp?year=2016&month=03&day=22&id=123456这样的网址和http://54sh.csu.edu.cn/readnews/2016/03/22/123456这样的网址你更喜欢哪一个呐?我想都是喜欢下面的吧,我随便举得例子虽然不经典,但是也能看出URL重写的重要性了,下面我来讲如何去实现这样的功能。

  在VirtualHost里面添加重写选项:

<IfModule mod_rewrite.c>

   RewriteEngine on

   RewriteRule  ^/readnews/([\d]+)/(\d]+)/([\d]+)/ ([\d]+)$  / readnews.jsp? year =$1 & month =$2& day =$3 & id =$4 [L]

</IfModule>

$1-$4指的是前面正则匹配项

这样就可以了~就是这么的简单~

其实吧,url这块知识还是蛮多的,结尾的[L] ("last|L")表示的是最后一个重写规则,告诉apache服务器重写将在执行这个规则后结束(前提是必须要执行,也就是说可以有好几个L规则)

其他还有很多我就不一一写了… http://httpd.apache.org/docs/trunk/rewrite/具体apache官方文档里面都有,我在这里粘一些常用的…

"redirect|R[=code]" 强制重定向。经常引用到触发可见的定向。默认情况下它是一个HTTP 302的临时重定向,但是你可以注明具体的HTTP 代码,比如你可以用[R=301]来表明这是一个永久重定向,这对搜索引擎抓取你重定向后的网页相当有用。

"proxy|P"   强制为代理

"forbidden|F"   403 禁止。告诉Apache响应请求时不提供页面。其原理就是Apache会发出一个403 HTTP相应,可以保护网站不被未经授权的或者其他盗链访问。

"nocase|NC" 忽略正则表达式中的大小写。它经常被用到{HTTP_HOST}服务器参数上,因为域名里面是不会区分大小写的。

"next|N"    回到第一条规则。可以让你的重写条件循环匹配,当你不知道{REQUEST_URI}有多少字符进行匹配的时候很有用。

"skip|S=N" 跳过下面的N条规则。

"noescape|NE"      在输出中不对URI作转义。此标记阻止mod_rewrite对重写结果应用常规的URI转义规则。 一般情况下,特殊字符(如‘%’, ‘$’, ‘;’等)会被转义为等值的十六进制编码。 此标记可以阻止这样的转义,以允许百分号等符号出现在输出中。

 

 

RewriteCond指令

RewriteCond TestString CondPattern [Flags]

RewriteCond指令定义了一个规则的条件,即在一个RewriteRule指令之前有一个或多个RewriteCond指令。 条件之后的重写规则仅在当前URI与pattern匹配并且符合这些条件的时候才会起作用。

RewriteCond也有反向引用,但和RewriteRule中用$N引用不同,它使用%N反向引用。

RewriteCond引用Apache变量%{ NAME_OF_VARIABLE},如%{HTTP_HOST}。

RewriteCond的条件模式(CondPattern)除了使用perl样式正则表达式,还有额外的规则:

1.  使用‘!’ 字符(惊叹号)来实现匹配的反转

2. ‘<CondPattern’ (词典顺序的小于)。将CondPattern视为纯字符串,与TestString以词典顺序相比较. 如果按词典顺序,TestString小于CondPattern,则为真。类似还有>,=。

3. ‘-d’ (是一个目录[directory])。将TestString视为一个路径名并测试它是否存在而且是一个目录.

4. ‘-f’ (是一个常规的文件[file])。将TestString视为一个路径名并测试它是否存在而且是一个常规的文件.

5. ‘-s’ (是一个非空的常规文件[size])。将TestString视为一个路径名并测试它是否存在而且是一个尺寸大于0的常规的文件.

6.‘-l’ (是一个符号连接[link])。将TestString视为一个路径名并测试它是否存在而且是一个符号连接.

7.‘-F’ (对子请求有效的业已存在的文件)。测试TestString是否一个有效的文件, 而且可以被服务器当前已经配置的所有存取控制所存取。 它用一个内部子请求来做判断,由于会降低服务器的性能,请小心使用

 

RewriteCond选项

‘nocase|NC’ (no case)。它使测试忽略大小写。此标记仅作用于TestString和CondPattern的比较, 而对文件系统和子请求的测试不起作用。

‘ornext|OR’ (or next condition)。它以OR方式组合若干规则的条件,而不是默认的AND。典型的例子如下:

RewriteCond %{REMOTE_HOST} ^host1.* [OR]

RewriteCond %{REMOTE_HOST} ^host2.* [OR]

RewriteCond %{REMOTE_HOST} ^host3.*

RewriteRule …some special stuff for any ofthese hosts…

如果不用这个标记,则必须使用三个 条件/规则。

 

服务器变量

HTTP变量

HTTP_USER_AGENT, HTTP_REFERER, HTTP_COOKIE,

HTTP_FORWARDED, HTTP_HOST,HTTP_PROXY_CONNECTION, HTTP_ACCEPT

连结和请求的变量

REMOTE_ADDR, REMOTE_HOST, REMOTE_USER,REMOTE_IDENT,

REQUEST_METHOD, SCRIPT_FILENAME, PATH_INFO,QUERY_STRING, AUTH_TYPE

服务器内部变量

DOCUMENT_ROOT, SERVER_ADMIN, SERVER_NAME,SERVER_ADDR,

SERVER_PORT, SERVER_PROTOCOL, SERVER_SOFTWARE

系统变量

TIME_YEAR, TIME_MON, TIME_DAY, TIME_HOUR,

TIME_MIN, TIME_SEC, TIME_WDAY, TIME

mod_rewrite特殊值

API_VERSION, THE_REQUEST, REQUEST_URI,REQUEST_FILENAME

 

URL重写举例

1.给子域名加www标记

RewriteCond %{HTTP_HOST}^([a-z.]+)?example\.com$ [NC]

RewriteCond %{HTTP_HOST} !^www\. [NC]

RewriteRule .?http://www.xample.com%{REQUEST_URI} [R=301,L]

这个规则抓取二级域名的%1变量,如果不是以www开始,那么就加www,以前的域名以及{REQUEST_URI}会跟在其后。

 

2.去掉域名中的www标记

RewriteCond %{HTTP_HOST} !^example\.com$ [NC]

RewriteRule .?http://example.com%{REQUEST_URI} [R=301,L]

 

3.去掉www标记,但是保存子域名

RewriteCond %{HTTP_HOST}^www\.(([a-z0-9_]+\.)?example\.com)$ [NC]

RewriteRule .? http://%1%{REQUEST_URI}[R=301,L]

这里,当匹配到1%变量以后,子域名才会在%2(内部原子)中抓取到,而我们需要的正是这个%1变量。

 

4. 防止图片盗链

一些站长不择手段的将你的图片盗链在他们网站上,耗费你的带宽。你可以加一下代码阻止这种行为。

RewriteCond %{HTTP_REFERER} !^$

RewriteCond %{HTTP_REFERER}!^http://(www\.)?example\.com/ [NC]

RewriteRule \.(gif|jpg|png)$ – [F]

如果{HTTP_REFERER}值不为空,或者不是来自你自己的域名,这个规则用[F]FLAG阻止以gif|jpg|png 结尾的URL

如果对这种盗链你是坚决鄙视的,你还可以改变图片,让访问盗链网站的用户知道该网站正在盗用你的图片。

RewriteCond %{HTTP_REFERER} !^$

RewriteCond %{HTTP_REFERER}!^http://(www\.)?example\.com/.*$ [NC]

RewriteRule \.(gif|jpg|png)$http://www.example.com/hotlinked.gif [R=301,L]

除了阻止图片盗链链接,以上规则将其盗链的图片全部替换成了你设置的图片。

你还可以阻止特定域名盗链你的图片:

RewriteCond %{HTTP_REFERER}!^http://(www\.)?leech_site\.com/ [NC]

RewriteRule \.(gif|jpg|png)$ – [F,L]

这个规则将阻止域名黑名单上所有的图片链接请求。

当然以上这些规则都是以{HTTP_REFERER}获取域名为基础的,如果你想改用成IP地址,用{REMOTE_ADDR}就可以了。

 

5.如果文件不存在重定向到404页面

RewriteCond%{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f

RewriteCond%{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d

RewriteRule .? /404.php [L]

-f匹配的是存在的文件名,-d匹配的存在的路径名

 

6.创建无文件后缀名链接

RewriteCond %{REQUEST_FILENAME}.php -f

RewriteRule ^/?([a-zA-Z0-9]+)$ $1.php [L]

RewriteCond %{REQUEST_FILENAME}.html -f

RewriteRule ^/?([a-zA-Z0-9]+)$ $1.html [L]

如果文件是以.php为后缀,这条规则将被执行。

 

7.强制使用HTTPS

RewriteCond %{HTTPS} !on

#RewriteCond %{SERVER_PORT} !^443$

RewriteCond %{HTTP_HOST}^([a-z.]+)?example\.com$ [NC]

RewriteRule ^(.*)$  https://xample.com$1 [R=301,L]

判断HTTPS服务可以判断安全端口(一般是443),也可以通过HTTPS变量。将example.com域名下所有url都强制使用https服务。

如果不判断域名,可以这样:

RewriteCond %{HTTPS} !on

RewriteRule ^/?(.*)$  https://%{SERVER_NAME}/$1 [R=301,L]

这里的$1前面有斜杠/,其实是匹配模式去掉了斜杠的原因,和上面效果是一样的

 

1 0