今天在我不务正业的 捣鼓了一上午之后  终于把这个.htaccess给玩入门了  起码 简单点的 url重写是没得毛病了

对于 htaccess 来完成 网站 允许/屏蔽  某些ip 或者ip端 访问  实在是很轻松的事  百度搜索下就可以很轻松的找到如下的代码 

//这个开始的第一行 就是确立 禁止 和允许的顺序 例如 当前就是 写的 先允许 后禁止
order allow,deny 
deny from all
allow from ::1

上面的代码   一次就是说的  执行顺序  先执行允许  再 执行禁止

然后  第二行是说的  禁止全部

第三行 说的  允许本地访问    对于程序来说 本地ip是::1  不是127.0.0.1

 

但是显然  我上面的代码是个失败的案例   因为  order 的顺序是  先允许 再禁止  我先允许了本地访问   接着又禁止 全部访问  

实际的效果就是  谁都无法访问了   只要改成这样 就可以允许我本地,以及这几个ip访问了  其他ip依旧是无法访问的

order deny,allow
deny from all
allow from ::1
allow from 127.0.0.1
allow from 123.132.1.14

以上就是 禁止某些ip  或者 允许某些ip访问的 例子了  不过 相对于现在 项目基本是单一入口  前台和后台管理都是一个入口下面的  如果这样操作显然是不合理的 限制ip后 前台普通用户也没法访问了   

所以 我们应该需要  仅仅对 后台的页面 进行 ip过滤  仅允许部分白名单ip访问

一上午看了不少教程  终于把我这个小白给教会了  让我学会了俩个。。。恩、、不知道叫啥   姑且叫它 htaccess  的方法把

RewriteCond    姑且叫他 重写的条件

RewriteRule   姑且叫他 重写的集体执行

 

既然是方法的话  那必然是可以传参的  他们俩都是可以传3个参的   第三个参不是必选项  但是前俩个参数 都是必选项的 

(默默的吐槽下  既然是参数 干嘛不用括号包裹  搞的我瞅了一上午 才看出来。。好吧 大概是我太蠢了)

RewriteCond  [待验证的字段]  [验证的方式(通常都是正则)]   [关键字(类似于 正则里面的修饰词  比如 可以让验证方式忽略大小写 什么的  )]

RewriteRule  [正则匹配的条件]  [正则替换的规则]   [关键字(类似于 正则里面的修饰词  比如 可以让验证方式忽略大小写 什么的  )]

先来简单的尝试下 

例如我有个php 页面  叫 a.php  例如是这样写的 仅仅打印下$_GET 就好了

 

<?php

echo "<pre>";
print_r($_GET);
echo "</pre>";

?>

 

然后我访问 这个php页面的   地址是这样的   http://www.xx.com/a.php

那么现在就可以在这个php文件下面 建立一个同级的 .htaccess 文件  记住这个文件没有后缀的哈

里面写上这么俩句

RewriteEngine On

RewriteRule  ^new-(\d+)-(\d+)\.html  a.php?act=new&uid=$1&page=$2

 

 

这样写好   我们再去访问  http://www.xx.com/new-1-2.html  页面就会重写  到a.php 上面去  最直观的表现就是  会打印出 这样的内容

Array
(
    [act] => new
    [uid] => 1
    [page] => 2
)

我们很成功的把url 完成的重写  因为是没有写 执行这个重新方法的 执行条件 也就是 RewriteCond   所以 会对 本站点的所有url都进行重写

那我们再试试加上RewriteCond 后 会是什么样子    重写规则改成以下样子

//依旧是正常的打印出来之前的样子
RewriteEngine On
RewriteCond  123456 ^123456&
RewriteRule  ^new-(\d+)-(\d+)\.html  a.php?act=new&uid=$1&page=$2


//再改成这样 就报错了 显然是没有进行url重写 所以没有找到页面 出错了
RewriteEngine On
RewriteCond  123456 ^1234$
RewriteRule  ^new-(\d+)-(\d+)\.html  a.php?act=new&uid=$1&page=$2

在正则里面  ^  是匹配开头   & 是匹配结尾   所以 上面的 第一次  是说的 匹配 1开头  6结尾的  123456    所以是匹配成功的  因为 我们前面输入的 就是123456

第二句也是一样的   匹配1开头  但是是4结尾了   这儿就不一样了  我们前面给出的字符串是  1开头  6结尾 所以 匹配不成功   不成功 则没有执行 下面的 RewriteRule

然后 RewriteCond   的第一个参数  除了可以写固定的字符串后 还可以写一些变量 具体有哪些变量 我没琢磨透  大致常用的有这几个

%{HTTP_HOST}    匹配域名
%{HTTP_REFERER} 来源页面链接
%{
REMOTE_ADDR} 用户访问ip
%{
HTTP_USER_AGENT} 浏览器的标识头 可以用来 判断是pc访问 还是 移动端访问 进而跳转不同端的控制器
%{REQUEST_URI} 当前的url地址 不包含 域名 例如 http://www.baidu.com/a.php 那就是/a.php
这些 基本都是  访问带过来的 协议头  在php 里面可以 用print_r($_SERVER);  打印看看的


我们可以这样 打印下 .htaccess 获取的这些变量的值的 例如直接写个重写
RewriteRule  ^new-(\d+)-(\d+)\.html  a.php?act=new&uid=$1&page=$2&host=%{HTTP_HOST}&HTTP_USER_AGENT=%{REQUEST_URI}

再访问我们之前的那页面 就可以打印出这些内容了
Array
(
    [act] => new
    [uid] => 1
    [page] => 2
    [host] => localhost
    [HTTP_USER_AGENT] => /demo/case/new-1-2.html
)

在了解了这些之后   我们就大干一场  完成我们给后端管理页面 设置仅允许白名单访问的任务了

假如  我们的后端管理是类似这样的url    http://www.xx.com/admin-main-index

那么  我们需要这样的代码 

RewriteEngine On
RewriteCond  %{REQUEST_URI} ^/admin
RewriteCond  %{HTTP_HOST} !^(::1|127.0.0.1|138.174.(\d+).(\d+))
RewriteRule  .  404.html

上面的代码 就是说   先进行条件匹配判断  

第一句条件   判断域名后面 是否是 admin 开头   这儿并不需要判断结尾  因为 admin控制器下面 会有很多页面的  所以 只要是admin开头 那么 我们都不放过  

第二句条   这儿 我开头的用的 !^      ^是进行开头匹配    !^  就相反了  是进行的开头不匹配    也就是说  来访的ip  不在 后面的 ip或者 ip段  就视为匹配成功   如果2个条件 都匹配成功了  就执行 第三句  url重写   直接重写到404.html页面  也就阻止了  用户的访问  

 

其实想想。  这什么仅允许白名单访问 后端页面   用php实现起来 简直不要太轻松了  还能记录下 不符合要求的名单信息什么的。。。貌似 压根没必要用这个 htaccess 来限制  = =

然后 还有些 修饰词的引用  例如 

[NC]    忽略 url的大小写   跟在重写条件后面用的  第三个参数 

[L]   最后一条重写   不过 我貌似用起来没感觉  加了这修饰词  后 还是会继续向下重写  不知道是什么鬼、、跟在重写操作后面用的  第三个参数 

[G]  重写并报废弃还是什么的。。。。昂 

算了  这个内容挺多的   想了解的小伙伴们 可以看看这篇文章的   里面写的挺详细的.htaccess 详解

最主要的掌握知识点 就是正则了  这个也是 很多语言 做字符串 批处理时候 会用到的   简单了解下 就可以入门的 并不会太复杂  后续加深的话  经常用用就了解的多了 

比如 简单的  万能正则表达式   (.*?)     比如 匹配  我爱你,我的家   这句话里面的   爱你,我的    就可以直接  用 我(.*?)家    

咳咳 跑题了   洗脚水也泡冷了   那么 晚安了 各位

  

                                                             
------------------------该文章来自一只贼蠢贼蠢的程序员