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

PHP 取得客戶端螢幕解析度:前端 JS 傳遞 + 後端接收完整方案

     編輯:PHP 綜合知識

核心觀念:PHP 運行於伺服器,無法直接存取客戶端硬體資訊

螢幕解析度、視口大小、裝置像素比等資訊**只存在於瀏覽器端**,必須透過 JavaScript 取得,再以 AJAX、Cookie、Session、URL 參數等方式傳給 PHP。

方案一:AJAX 非同步上報(推薦,不阻塞頁面)

<!-- 頁面 head 內嵌 -->
<script>
(function() {
    function reportScreen() {
        var data = {
            screen_width: window.screen.width,
            screen_height: window.screen.height,
            avail_width: window.screen.availWidth,
            avail_height: window.screen.availHeight,
            device_pixel_ratio: window.devicePixelRatio || 1,
            viewport_width: document.documentElement.clientWidth,
            viewport_height: document.documentElement.clientHeight,
            color_depth: window.screen.colorDepth,
            orientation: window.screen.orientation?.type || 'unknown'
        };

        // 發送至後端 API
        fetch('/api/screen-report', {
            method: 'POST',
            headers: {'Content-Type': 'application/json'},
            body: JSON.stringify(data),
            credentials: 'include', // 攜帶 Cookie/Session
            keepalive: true // 頁面卸載時仍嘗試送出
        }).catch(console.error);
    }

    // 頁面載入完成後上報
    if (document.readyState === 'complete') {
        reportScreen();
    } else {
        window.addEventListener('load', reportScreen);
    }

    // 視口變化時可選上報 (resize/orientationchange)
    var resizeTimer;
    window.addEventListener('resize', function() {
        clearTimeout(resizeTimer);
        resizeTimer = setTimeout(reportScreen, 500);
    });
})();
</script>

後端 API 接收與儲存

<?php
// /api/screen-report.php
header('Content-Type: application/json');

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(['error' => 'Method not allowed']);
    exit;
}

$input = json_decode(file_get_contents('php://input'), true);
if (!$input) {
    http_response_code(400);
    echo json_encode(['error' => 'Invalid JSON']);
    exit;
}

// 驗證必要欄位
$required = ['screen_width', 'screen_height', 'viewport_width', 'viewport_height'];
foreach ($required as $field) {
    if (!isset($input[$field]) || !is_numeric($input[$field])) {
        http_response_code(400);
        echo json_encode(['error' => "Missing field: $field"]);
        exit;
    }
}

// 關聯用戶/Session
$sessionId = session_id();
if (!$sessionId) session_start();
$userId = $_SESSION['user_id'] ?? null;

// 儲存資料庫 (範例)
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8mb4', 'root', '');
$stmt = $pdo->prepare('
    INSERT INTO client_screen_info (session_id, user_id, screen_width, screen_height, avail_width, avail_height, dpr, viewport_width, viewport_height, color_depth, orientation, created_at)
    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())
    ON DUPLICATE KEY UPDATE
        screen_width=VALUES(screen_width), screen_height=VALUES(screen_height),
        viewport_width=VALUES(viewport_width), viewport_height=VALUES(viewport_height),
        updated_at=NOW()
');
$stmt->execute([
    $sessionId, $userId,
    $input['screen_width'], $input['screen_height'],
    $input['avail_width'] ?? 0, $input['avail_height'] ?? 0,
    $input['device_pixel_ratio'] ?? 1,
    $input['viewport_width'], $input['viewport_height'],
    $input['color_depth'] ?? 24,
    $input['orientation'] ?? 'unknown'
]);

echo json_encode(['success' => true]);
?>

方案二:Cookie 儲存(簡單、後續請求自動攜帶)

<script>
// 寫入 Cookie (前端)
document.cookie = 'screen_info=' + encodeURIComponent(JSON.stringify({
    w: screen.width,
    h: screen.height,
    vw: document.documentElement.clientWidth,
    vh: document.documentElement.clientHeight,
    dpr: devicePixelRatio || 1
})) + '; path=/; max-age=2592000; SameSite=Lax'; // 30 天
</script>
<?php
// 後端讀取 Cookie
if (isset($_COOKIE['screen_info'])) {
    $screen = json_decode(urldecode($_COOKIE['screen_info']), true);
    if ($screen) {
        // 直接使用 $screen['w'], $screen['h']...
        // 例:判斷是否行動裝置
        $isMobile = ($screen['w'] ?? 1920) < 768;
    }
}
?>

方案三:URL 參數傳遞(首次導向、SSR 需求)

<script>
// 首頁導向帶參數 (僅示範,實際會造成重導向迴圈需加判斷)
if (!new URLSearchParams(window.location.search).has('scr')) {
    var scr = [screen.width, screen.height, devicePixelRatio || 1].join('x');
    window.location.href = window.location.pathname + '?scr=' + scr + '&' + window.location.search.slice(1);
}
</script>
<?php
// 後端接收
if (isset($_GET['scr'])) {
    [$w, $h, $dpr] = array_pad(explode('x', $_GET['scr']), 3, [1920, 1080, 1]);
    // 立即可用於伺服器端渲染決策
}
?>

資料庫設計建議

CREATE TABLE client_screen_info (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    session_id VARCHAR(64) NOT NULL,
    user_id BIGINT UNSIGNED NULL,
    screen_width SMALLINT UNSIGNED NOT NULL,
    screen_height SMALLINT UNSIGNED NOT NULL,
    avail_width SMALLINT UNSIGNED DEFAULT 0,
    avail_height SMALLINT UNSIGNED DEFAULT 0,
    dpr DECIMAL(3,2) DEFAULT 1.00,
    viewport_width SMALLINT UNSIGNED NOT NULL,
    viewport_height SMALLINT UNSIGNED NOT NULL,
    color_depth TINYINT UNSIGNED DEFAULT 24,
    orientation ENUM('portrait-primary','landscape-primary','portrait-secondary','landscape-secondary','unknown') DEFAULT 'unknown',
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    UNIQUE KEY uk_session (session_id),
    KEY idx_user (user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

應用場景

場景用途實作建議
響應式圖片尺寸依螢幕寬度輸出適當 srcsetSSR 時用 Cookie/URL 參數;CSR 用 JS 直接設定
行動版/桌面版佈局切換PHP 直接輸出不同模板首次請求用 URL 參數或 Session 快取
廣告位尺寸決定依視口大小請求對應廣告AJAX 上報後快取至 Session/Redis
使用者體驗分析統計解析度分布、DPR 分布批次寫入資料庫,定期匯總
Canvas/WebGL 畫布大小乘以 DPR 避免模糊前端直接用,無需 PHP

隱私與合規提醒

  • 螢幕解析度屬於**裝置指紋**組成部分,GDPR/個資法視為個人資料。
  • 隱私權政策需說明收集目的、保留期限、用戶拒絕權利。
  • 避免將解析度與可識別身分資訊(姓名、Email、精確 IP)直接關聯儲存。
  • 提供 `Do Not Track` 或自訂選項讓用戶停用上報。

總結

PHP 取得螢幕解析度**必須仰賴前端 JS**,推薦 **AJAX 非同步上報 + 後端快取 (Session/Redis/DB)** 架構,兼顧即時性、效能與隱私合規。避免同步阻塞導向,善用 `fetch(keepalive)` 確保資料送達。

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