IP判段后跳转,判断说白了就是段后代码让不同来源的访客自动去不同的页面。这事听着简单,进行做起来全是页面细节坑。我见过有人用一段PHP写死十几个if-else,跳转结果三个月后自己都看不懂哪段代码管哪片网段。判断
先看最实用的段后代码场景——公司内网和外网访问同一域名,要分流到不同系统。进行拿PHP举例,页面$_SERVER['REMOTE_ADDR']拿到访客IP,跳转再用ip2long()转成整数比较。判断比如内网段192.168.1.0/24,段后代码判断逻辑就是进行:
$ip = ip2long($_SERVER['REMOTE_ADDR']); $net = ip2long('192.168.1.0'); $mask = ip2long('255.255.255.0'); if (($ip & $mask) == ($net & $mask)) { header('Location: /internal/'); } else { header('Location: /public/'); } exit; 这段代码的关键在于按位与运算,把IP和子网掩码做AND操作,页面比对网络号。跳转别用字符串截取,IPv6一进来全完蛋。也别直接比较IP段字符串,'192.168.1.10'和'192.168.1.2'按字典序比较会出错,必须转成数字。
但光会写不行,得知道什么时候不能用这种方案。CDN或反向代理后面,REMOTE_ADDR拿到的是代理服务器的IP,所有访客都成一个IP了。这时候要读HTTP_X_FORWARDED_FOR头,但这个头能伪造——有人直接curl加个X-Forwarded-For: 8.8.8.8就混过去了。生产环境必须只信任已知代理IP,再取转发头里的第一个IP。
还有个隐蔽问题:用户IP在移动网络下会频繁变化。坐地铁从东单到西单,IP段可能换了三次。如果判断结果导致页面跳转,用户刚打开A页面就被弹到B页面,体验极差。我见过某视频站按IP段区分省市,结果用户跨区移动时反复跳转,投诉率飙升。后来他们改成首次访问时记录IP段,24小时内不重复判断,才稳住。
跳转方式也分三六九等。服务端header('Location')是302临时重定向,搜索引擎会认为页面临时搬家。如果IP段对应的是永久性资源分区,用301更合适。JavaScript的window.location.replace()不会在浏览器历史里留记录,适合不想让用户点返回键回到旧页的场景。但JS跳转会闪烁一下,对速度敏感的业务别用。
最后说个真事。去年帮朋友调一个按IP段跳转到不同语言站点的系统,发现他判断IP段用的是strpos($_SERVER['REMOTE_ADDR'], '58.')这种写法。这会把58.1.1.1和58.254.254.254全归一类,连58.xxx开头的美国IP都算进去。那哥们儿上线第二天就收到海外用户邮件,说为啥自己中文站英文站来回蹦。改成子网掩码计算后,问题才解决。
写这段代码前先问自己三个问题:IP是从哪个网络层级拿到的?跳转是临时还是永久的?用户遇到误判时怎么兜底?想清楚这三件事,代码怎么写都不会跑偏。