This repository has been archived on 2026-06-20. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
2025-01-14 01:21:42 +08:00

201 lines
7.1 KiB
PHP

<?php
require 'config.php';
function callApi($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); // 10秒连接超时
curl_setopt($ch, CURLOPT_TIMEOUT, 30); // 30秒执行超时
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Accept: application/json'
]);
// 禁用SSL验证
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$response = curl_exec($ch);
if (curl_errno($ch)) {
$error_msg = curl_error($ch);
curl_close($ch);
return json_encode(['error' => $error_msg]);
}
curl_close($ch);
return $response;
}
if (isset($_SERVER['HTTP_ACCEPT']) && strpos($_SERVER['HTTP_ACCEPT'], 'text/event-stream') !== false) {
// 设置SSE头信息
header('Content-Type: text/event-stream; charset=UTF-8');
header('Cache-Control: no-cache, must-revalidate');
header('Connection: keep-alive');
header('X-Accel-Buffering: no'); // 禁用Nginx缓冲
header('Access-Control-Allow-Origin: *');
header('Content-Encoding: none'); // 禁用压缩
// 设置脚本超时时间
set_time_limit(0);
ignore_user_abort(true);
// 禁用输出缓冲
if (ob_get_level()) {
ob_end_clean();
}
ob_implicit_flush(true);
// 发送心跳包保持连接
function sendHeartbeat() {
echo ": heartbeat\n\n";
ob_flush();
flush();
}
$total = count($links);
$completed = 0;
// 发送初始心跳
sendHeartbeat();
// 检查连接是否中断
if (connection_aborted()) {
exit;
}
foreach ($links as $link) {
$startTime = microtime(true);
$result = callApi($link);
$endTime = microtime(true);
$executionTime = round(($endTime - $startTime) * 1000, 2); // 毫秒
$completed++;
$progress = round(($completed / $total) * 100);
$data = [
'link' => $link,
'start_time' => date('Y-m-d H:i:s', $startTime),
'end_time' => date('Y-m-d H:i:s', $endTime),
'execution_time' => $executionTime,
'result' => $result,
'progress' => $progress
];
echo "data: " . json_encode($data) . "\n\n";
ob_flush();
flush();
}
echo "event: complete\ndata: {}\n\n";
exit;
}
?>
<!DOCTYPE html>
<html>
<head>
<title>API 调用工具</title>
<style>
body { font-family: Arial, sans-serif; padding: 20px; }
#results { margin-top: 20px; white-space: pre-wrap; }
.result-block { margin-bottom: 20px; padding: 10px; border: 1px solid #ddd; }
.progress-container {
width: 100%;
background-color: #f3f3f3;
margin: 20px 0;
border-radius: 5px;
overflow: hidden;
}
.progress-bar {
width: 0;
height: 30px;
background-color: #4caf50;
text-align: center;
line-height: 30px;
color: white;
transition: width 0.3s ease;
}
</style>
</head>
<body>
<h1>API 调用工具</h1>
<button id="executeBtn">执行 API 调用</button>
<div class="progress-container">
<div id="progressBar" class="progress-bar">0%</div>
</div>
<div id="results"></div>
<script>
document.getElementById('executeBtn').addEventListener('click', function() {
const resultsDiv = document.getElementById('results');
resultsDiv.innerHTML = '<div id="result-container"></div>';
fetch(window.location.href, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
}
}).then(() => {
const eventSource = new EventSource(window.location.href);
const resultContainer = document.getElementById('result-container');
eventSource.onmessage = function(event) {
const data = JSON.parse(event.data);
// 更新进度条
const progressBar = document.getElementById('progressBar');
progressBar.style.width = data.progress + '%';
progressBar.textContent = data.progress + '%';
// 添加新结果
const resultBlock = document.createElement('div');
resultBlock.className = 'result-block';
resultBlock.innerHTML = `
<strong>访问链接:</strong> ${data.link}<br>
<strong>开始时间:</strong> ${data.start_time}<br>
<strong>结束时间:</strong> ${data.end_time}<br>
<strong>执行时间:</strong> ${data.execution_time}ms<br>
<strong>返回结果:</strong> ${data.result}
`;
resultContainer.appendChild(resultBlock);
};
eventSource.addEventListener('complete', function() {
eventSource.close();
progressBar.style.backgroundColor = '#4caf50';
progressBar.textContent = '完成';
});
let reconnectAttempts = 0;
const maxReconnectAttempts = 3;
eventSource.onerror = function(e) {
if (e.eventPhase === EventSource.CLOSED) {
// 服务器主动关闭连接
eventSource.close();
if (progressBar.textContent !== '完成') {
resultsDiv.innerHTML = '连接已关闭';
}
} else {
// 连接中断,尝试重连
if (reconnectAttempts < maxReconnectAttempts) {
reconnectAttempts++;
setTimeout(function() {
eventSource = new EventSource('');
}, 1000 * reconnectAttempts); // 指数退避
} else {
eventSource.close();
resultsDiv.innerHTML = '连接中断,请重试';
}
}
};
// 添加心跳检测
const heartbeatInterval = setInterval(() => {
if (eventSource.readyState === EventSource.CLOSED) {
clearInterval(heartbeatInterval);
}
}, 5000);
});
});
</script>
</body>
</html>