域名转接在不同人的口中含义差别很大,有人指旧域名跳转到新域名,有人是多个域名统一指向主站,还有人指代短链接生成。但不管哪一种场景,落到代码层面,核心逻辑都一致:用户访问 A 域名,服务器下发指令,让浏览器跳转访问 B 地址,这个指令就是 HTTP 重定向。
一、PHP 服务端重定向
先讲使用最广泛的 PHP 实现方式。原理很简单,PHP 脚本读取当前请求域名,和预设映射规则比对,匹配成功就返回 Location 响应头。下面这段代码是网上流传最多的版本:
<?php
$currentDomain = $_SERVER['HTTP_HOST'];
$targetDomain = 'https://newdomain.com';
if ($currentDomain == 'olddomain.com') {
header('HTTP/1.1 301 Moved Permanently');
header('Location: ' . $targetDomain);
exit();
}
?>
这里有几个细节需要留意。$_SERVER['HTTP_HOST'] 获取的域名不带协议,类似 olddomain.com 或者 www.olddomain.com,和浏览器地址栏展示内容不完全相同。调用 header 函数之前不能输出任何内容,哪怕是空格或者 BOM 头,都会触发 headers already sent 报错。必须加上 exit(),不然后续代码会继续执行,就算用户已经跳转,服务器依旧会执行多余查询。

如果需要处理多个域名,把 if 判断替换成数组映射,维护起来更方便:
$rules = [
'olddomain.com' => 'https://newdomain.com',
'blog.olddomain.com' => 'https://blog.newdomain.com',
];
$host = $_SERVER['HTTP_HOST'];
if (isset($rules[$host])) {
header('HTTP/1.1 301 Moved Permanently');
header('Location: ' . $rules[$host]);
exit();
}
数组结构的好处是新增跳转规则只需要增加一行配置,不用改动核心逻辑。数组键值必须和 HTTP_HOST 获取内容完全匹配,www 前缀、大小写都要对应上。
PHP 的 header 重定向属于服务端执行,浏览器收到状态码之后发起新请求。还有客户端跳转方案,依靠 HTML 的 meta 标签:
二、HTML meta 客户端跳转
<meta http-equiv="refresh" content="3; url=http://newdomain.com">
content 里面的 3 代表延迟跳转秒数,改成 0 就是立刻跳转。这个方案的优势是不依赖任何后端环境,静态 HTML 文件就能实现。缺点同样明显,搜索引擎处理 meta refresh 的权重规则和 301 不一样,如果目标是保留旧域名搜索权重,meta refresh 并不合适。
三、iframe / frameset 隐性转发
还有一种比较隐蔽的方案,用 iframe 或者 frameset 嵌入目标页面,浏览器地址栏不会变化,也就是隐性转发。参考代码如下:
<frameset framespacing="0" border="0" rows="0" frameborder="0">
<frame name="main" src="http://newdomain.com" scrolling="auto" noresize>
</frameset>
frameset 隐性转发,搜索引擎抓取到的只是空白框架,实际内容嵌套在 iframe 里面,几乎没有 SEO 效果。而且移动端浏览器对 frameset 支持越来越差,不少手机浏览器会直接忽略这段代码。如果只需要让用户看到页面,不在乎搜索引擎收录,可以临时应急。正规建站项目不推荐这种方案。
四、开源方案:forward-domain
不想手写代码的话,GitHub 上有现成开源项目可以直接部署。lobovkin/forward-domain 这个项目使用简单,不需要服务器,不用写代码,将域名 CNAME 记录指向 r.forwarddomain.net,再添加一条 TXT 记录设置跳转目标。TXT 记录格式为 forward-domain=https://newdomain.com/*,末尾星号代表同步传递 URL 路径,用户访问 old.com/about,会跳转到 newdomain.com/about。
项目默认使用 301 永久重定向,如果需要切换为 302,在 TXT 记录增加 http-status=302 配置。301 和 302 对 SEO 影响不同:301 告知搜索引擎地址永久变更,权重会转移到新地址;302 属于临时跳转,搜索引擎不会转移权重。更换域名不再恢复使用就选 301,A/B 测试或者临时维护页面使用 302。
五、Nginx / Apache 配置
服务器如果是 Nginx,直接在配置文件编写 rewrite 规则,效率高于 PHP,不需要运行 PHP-FPM:
server {
listen 80;
server_name olddomain.com www.olddomain.com;
return 301 https://newdomain.com$request_uri;
}
$request_uri 会完整传递原始请求路径和参数,用户访问 old.com/page?id=123,跳转后地址保留 newdomain.com/page?id=123。不添加这个变量,所有访问都会直接跳转到 newdomain.com 首页,丢失路径信息。Apache 服务器可以在 .htaccess 写入 Redirect 301 / https://newdomain.com/ 实现类似效果,处理复杂路径映射灵活性不如 Nginx rewrite。
六、重定向循环排查
很多人踩过重定向循环的坑。A 域名跳转 B 域名,B 域名配置又跳转回 A,浏览器就会无限来回跳转。排查方法很简单,用 curl 命令查看响应头:
curl -I https://olddomain.com
查看返回的 Location 指向地址和状态码。如果 Location 依旧指向 olddomain.com 本身,就属于循环跳转。解决办法是重定向规则排除目标域名,或者保证目标域名服务器没有反向跳转配置。
七、方案对比与总结
域名转接的代码本身并不复杂,难点在于选对实现方式,把控细节。确定使用 301 还是 302、服务端跳转还是客户端跳转、手写代码还是开源项目,每种方案都有适用场景。拿不准的时候,先用 curl 检测响应头,比阅读大量教程更直接有效。