首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

HTTP_HOST vs SERVER_NAME:端口號差異與實際應用場景

     編輯:PHP 相關知識

核心區別

HTTP_HOST = SERVER_NAME + (SERVER_PORT != 80 && SERVER_PORT != 443 ? ':' . SERVER_PORT : '')

詳細對比

變量來源包含端口典型值
$_SERVER['HTTP_HOST']客戶端請求頭 Host:是(非標準端口時)example.com 或 example.com:8080
$_SERVER['SERVER_NAME']服務器配置否example.com
$_SERVER['SERVER_PORT']服務器監聽端口純端口號80、443、8080

場景演示

<?php
// 請求:https://example.com:8080/path
var_dump($_SERVER['HTTP_HOST']);     // string(17) "example.com:8080"
var_dump($_SERVER['SERVER_NAME']);   // string(11) "example.com"
var_dump($_SERVER['SERVER_PORT']);   // string(4) "8080"

// 請求:https://example.com/path (443)
var_dump($_SERVER['HTTP_HOST']);     // string(11) "example.com" (標準端口不顯示)
var_dump($_SERVER['SERVER_NAME']);   // string(11) "example.com"
var_dump($_SERVER['SERVER_PORT']);   // string(3) "443"
?>

實際應用指南

1. 生成絕對 URL(推薦 HTTP_HOST)

<?php
function currentUrl() {
    $scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
    return $scheme . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
}
// 正確處理非標準端口:https://example.com:8080/foo
?>

2. 多域名站點識別(用 SERVER_NAME)

<?php
// Apache VirtualHost / Nginx server_name 配置的主域名
$mainDomain = $_SERVER['SERVER_NAME']; // 不受客戶端 Host 頭偽造影響
if ($mainDomain === 'api.example.com') { /* API 邏輯 */ }
?>

3. 防止 Host 頭攻擊

<?php
$allowedHosts = ['example.com', 'www.example.com', 'api.example.com'];
$host = $_SERVER['HTTP_HOST'];
// 移除端口部分比較
$host = preg_replace('/:\d+$/', '', $host);
if (!in_array($host, $allowedHosts, true)) {
    header('HTTP/1.1 400 Bad Request');
    exit('Invalid Host header');
}
?>

Nginx/Apache 配置影響

  • Nginx server_name 決定 SERVER_NAME
  • Apache ServerName / ServerAlias 決定 SERVER_NAME
  • UseCanonicalName On (Apache) 強制 SERVER_NAME 為配置值,忽略客戶端 Host
  • 代理鏈下 HTTP_HOST 可能被改寫,需配合 proxy_set_header Host $host;

結語

HTTP_HOST 來自客戶端,含端口,用於生成面向用戶的 URL;SERVER_NAME 來自服務器配置,不含端口,用於內部邏輯判斷。理解二者差異,正確選擇,能避免端口丟失、Host 頭注入等安全與功能 Bug。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved