利用瀏覽器會自動執行 <script src="...> 返回的 JavaScript 代碼特性,讓 PHP 腳本輸出 JS 代碼而非 HTML,實現「隱性」的後端邏輯執行與資料回傳。常用於跨域計數器、廣告追蹤、第三方嵌入式服務。
<html> <head><title>計數器展示頁</title></head> <body> <h1>網站造訪次數:<span id="counter">載入中...</span></h1> <!-- 隱性調用 PHP 計數器 --> <script src="counter.php"></script> </body> </html>
<?php
$file = "count.txt";
// 1. 讀取現有計數
$fp = fopen($file, "r");
$count = fread($fp, filesize($file));
fclose($fp);
// 2. 遞增
$count++;
// 3. 寫回
$fp = fopen($file, "w");
fwrite($fp, $count);
fclose($fp);
// 4. 輸出 JavaScript 代碼更新頁面
// 使用 document.write 直接寫入 DOM (舊式但相容性佳)
// 現代建議:document.getElementById('counter').textContent = $count;
echo "document.getElementById('counter').textContent = '$count';";
// 替代寫法:回呼函式模式 (支援多實例、非同步)
// echo "window.counterCallback($count);";
?>
<?php
// api.php - 支援 callback 參數的 JSONP 端點
header('Content-Type: application/javascript; charset=utf-8');
$data = [
'timestamp' => time(),
'visits' => rand(1000, 9999),
'status' => 'ok'
];
$callback = $_GET['callback'] ?? 'callback';
// 安全:僅允許字母數字底線
if (!preg_match('/^[a-zA-Z0-9_]+$/', $callback)) {
$callback = 'callback';
}
echo "$callback(" . json_encode($data) . ");";
?>
<script>
function handleData(data) {
console.log('API 回傳:', data);
document.getElementById('visits').textContent = data.visits;
}
</script>
<script src="api.php?callback=handleData"></script>
| 優點 | 缺點 |
|---|---|
| 繞過同源策略 (CORS) | 僅支援 GET 請求 |
| 無需 AJAX/JS 技術即可整合 | 安全風險:XSS、CSRF、腳本注入 |
| 極簡整合:一行 script 標籤 | 阻塞頁面渲染 (除非加 async/defer) |
| 支援舊版瀏覽器 (IE6+) | 難以處理錯誤狀態、超時、重試 |
| 可輸出任意 JS 邏輯 | 被廣告攔截器視為追蹤腳本攔截 |
// PHP 端
header('Access-Control-Allow-Origin: *');
header('Content-Type: application/json');
echo json_encode($data);
// 前端
fetch('api.php')
.then(r => r.json())
.then(data => updateUI(data))
.catch(err => console.error(err));
// track.php
header('Content-Type: image/gif');
header('Content-Length: 43'); // 1x1 透明 GIF
echo base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7');
// 記錄 $_SERVER['HTTP_REFERER'], $_GET 等資訊
<img src="track.php?event=pageview&ref=homepage" width="1" height="1" alt="" />
window.addEventListener('beforeunload', () => {
navigator.sendBeacon('/analytics.php', JSON.stringify({page: location.pathname}));
});
callback 參數格式 (僅字母數字底線)Content-Type: application/javascript隱性調用是早期 Web 開發的經典技巧,現代專案應優先採用 CORS + Fetch/Beacon 架構,僅在相容舊系統或極簡嵌入場景下使用。