HTTP 狀態碼 **301 Moved Permanently** 告訴瀏覽器和搜索引擎:**資源永久移動到新 URL**。瀏覽器會自動跳轉,搜索引擎會將舊頁權重(PageRank、收錄、關鍵詞排名)轉移到新頁,**是域名遷移、網站改版、URL 規範化的必備手段**。
<?php
// redirect_301.php - 放在舊頁入口或公共引導文件最頂部
// 1. 確定目標域名/路徑
$newHost = 'https://www.newdomain.com'; // 新域名
$requestUri = $_SERVER['REQUEST_URI'] ?? '/'; // 保留原路徑與查詢串
// 2. 判斷是否需要重定向(避免循環)
$currentHost = $_SERVER['HTTP_HOST'] ?? '';
if ($currentHost !== 'www.newdomain.com') { // 舊域名或裸域
// 3. 發送 301 頭
header('HTTP/1.1 301 Moved Permanently', true, 301);
// 4. Location 頭必須是絕對 URL
header('Location: ' . $newHost . $requestUri);
exit;
}
// 正常業務邏輯...
?>
<?php
$oldDomains = ['old.com', 'www.old.com', 'legacy.site'];
$newDomain = 'https://www.newsite.com';
if (in_array($_SERVER['HTTP_HOST'] ?? '', $oldDomains)) {
header('HTTP/1.1 301 Moved Permanently');
header('Location: ' . $newDomain . $_SERVER['REQUEST_URI']);
exit;
}
<?php
if (strpos($_SERVER['HTTP_HOST'] ?? '', 'www.') !== 0) {
header('HTTP/1.1 301 Moved Permanently');
header('Location: https://www.' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
exit;
}
<?php
if (empty($_SERVER['HTTPS']) || $_SERVER['HTTPS'] === 'off') {
header('HTTP/1.1 301 Moved Permanently');
header('Location: https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
exit;
}
<?php
$map = [
'/article.php' => '/article/',
'/product.php' => '/product/',
'/category.php' => '/category/',
];
$uri = $_SERVER['REQUEST_URI'];
$parsed = parse_url($uri);
$path = $parsed['path'] ?? '';
$query = $parsed['query'] ?? '';
if (isset($map[$path]) && preg_match('/id=(\d+)/', $query, $m)) {
$newUrl = 'https://' . $_SERVER['HTTP_HOST'] . $map[$path] . $m[1];
header('HTTP/1.1 301 Moved Permanently');
header('Location: ' . $newUrl);
exit;
}
**生產環境強烈建議在 Web 服務器層面做 301**,避免啟動 PHP 進程,延遲更低、併發更強。
server {
listen 80;
server_name old.com www.old.com;
return 301 https://www.newsite.com$request_uri;
}
# 裸域跳 www
server {
listen 80 443 ssl;
server_name example.com;
return 301 https://www.example.com$request_uri;
}
RewriteEngine On
# 舊域名跳新域名
RewriteCond %{HTTP_HOST} ^(old\.com|www\.old\.com)$ [NC]
RewriteRule ^(.*)$ https://www.newsite.com/$1 [R=301,L]
# 裸域跳 www
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
# HTTP 跳 HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
| 錯誤 | 後果 | 正確做法 |
|---|---|---|
| 用 302/307 臨時重定向 | 權重不傳遞,SEO 受損 | 必須 301 |
| 重定向鏈過長(A→B→C) | 爬蟲中斷、用戶延遲 | 單步直達最終 URL |
| 所有舊頁跳首頁 | 軟 404、權重流失 | 一對一映射到相關新頁 |
| Location 用相對路徑 | 部分瀏覽器/爬蟲解析失敗 | 絕對 URL(含 scheme+host) |
| 未更新內部鏈接/站點地圖 | 產生大量 301 內部跳轉 | 全站掃描替換內部鏈接 |
PHP 實現 301 只需 `header('HTTP/1.1 301 Moved Permanently')` + `header('Location: 絕對URL')` + `exit`。但**生產環境首選 Nginx/Apache 層面**,性能更優、配置更清晰。遷移核心在於**一對一映射、避免重定向鏈、及時通知搜索引擎**。