Files
ai_dianshang/web/debug-cart-request.html

237 lines
8.2 KiB
HTML
Raw Normal View History

2025-11-28 15:18:10 +08:00
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>购物车请求调试工具</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 1200px;
margin: 20px auto;
padding: 20px;
}
.section {
margin: 20px 0;
padding: 15px;
border: 1px solid #ddd;
border-radius: 5px;
}
button {
padding: 10px 20px;
margin: 5px;
cursor: pointer;
background: #4CAF50;
color: white;
border: none;
border-radius: 4px;
}
button:hover {
background: #45a049;
}
.log {
background: #f5f5f5;
padding: 10px;
margin: 10px 0;
border-radius: 4px;
font-family: monospace;
white-space: pre-wrap;
max-height: 400px;
overflow-y: auto;
}
.success { color: green; }
.error { color: red; }
.info { color: blue; }
input {
width: 100%;
padding: 8px;
margin: 5px 0;
border: 1px solid #ddd;
border-radius: 4px;
}
</style>
</head>
<body>
<h1>🔧 购物车请求调试工具</h1>
<div class="section">
<h2>1. 环境信息</h2>
<div id="envInfo" class="log"></div>
</div>
<div class="section">
<h2>2. 配置 API 地址</h2>
<input type="text" id="apiUrl" placeholder="输入 API 地址例如http://104.244.91.212:8060/api/v1" value="http://104.244.91.212:8060/api/v1">
<input type="text" id="token" placeholder="输入 Token从 localStorage 获取)">
<button onclick="loadToken()">从 localStorage 加载 Token</button>
</div>
<div class="section">
<h2>3. 测试接口</h2>
<button onclick="testHealth()">测试健康检查</button>
<button onclick="testBanners()">测试轮播图(无需认证)</button>
<button onclick="testCart()">测试购物车(需要认证)</button>
<button onclick="testCORS()">测试 CORS 预检</button>
</div>
<div class="section">
<h2>4. 请求日志</h2>
<button onclick="clearLog()">清空日志</button>
<div id="log" class="log"></div>
</div>
<script>
// 显示环境信息
function showEnvInfo() {
const info = {
'当前页面': window.location.href,
'协议': window.location.protocol,
'主机名': window.location.hostname,
'端口': window.location.port,
'用户代理': navigator.userAgent,
'localStorage Token': localStorage.getItem('currentUser') ? '已存在' : '不存在'
};
let html = '';
for (let [key, value] of Object.entries(info)) {
html += `<div><strong>${key}:</strong> ${value}</div>`;
}
document.getElementById('envInfo').innerHTML = html;
}
// 加载 Token
function loadToken() {
try {
const user = localStorage.getItem('currentUser');
if (user) {
const userData = JSON.parse(user);
document.getElementById('token').value = userData.token || '';
log('✓ Token 已加载', 'success');
} else {
log('✗ localStorage 中没有找到用户信息', 'error');
}
} catch (e) {
log('✗ 加载 Token 失败: ' + e.message, 'error');
}
}
// 日志函数
function log(message, type = 'info') {
const logDiv = document.getElementById('log');
const time = new Date().toLocaleTimeString();
logDiv.innerHTML += `<div class="${type}">[${time}] ${message}</div>`;
logDiv.scrollTop = logDiv.scrollHeight;
}
function clearLog() {
document.getElementById('log').innerHTML = '';
}
// 通用请求函数
async function makeRequest(url, options = {}) {
log(`\n========== 开始请求 ==========`, 'info');
log(`URL: ${url}`, 'info');
log(`Method: ${options.method || 'GET'}`, 'info');
if (options.headers) {
log(`Headers: ${JSON.stringify(options.headers, null, 2)}`, 'info');
}
try {
const startTime = Date.now();
const response = await fetch(url, options);
const duration = Date.now() - startTime;
log(`\n响应状态: ${response.status} ${response.statusText}`,
response.ok ? 'success' : 'error');
log(`响应时间: ${duration}ms`, 'info');
// 显示响应头
log(`\n响应头:`, 'info');
response.headers.forEach((value, key) => {
log(` ${key}: ${value}`, 'info');
});
// 获取响应体
const contentType = response.headers.get('content-type');
let data;
if (contentType && contentType.includes('application/json')) {
data = await response.json();
log(`\n响应数据:\n${JSON.stringify(data, null, 2)}`, 'success');
} else {
data = await response.text();
log(`\n响应数据:\n${data}`, 'info');
}
log(`========== 请求完成 ==========\n`, 'info');
return { ok: response.ok, status: response.status, data };
} catch (error) {
log(`\n✗ 请求失败: ${error.message}`, 'error');
log(`错误类型: ${error.name}`, 'error');
log(`错误堆栈: ${error.stack}`, 'error');
log(`========== 请求失败 ==========\n`, 'error');
return { ok: false, error: error.message };
}
}
// 测试健康检查
async function testHealth() {
const apiUrl = document.getElementById('apiUrl').value;
const baseUrl = apiUrl.replace('/api/v1', '');
await makeRequest(`${baseUrl}/health`);
}
// 测试轮播图
async function testBanners() {
const apiUrl = document.getElementById('apiUrl').value;
await makeRequest(`${apiUrl}/banners`);
}
// 测试购物车
async function testCart() {
const apiUrl = document.getElementById('apiUrl').value;
const token = document.getElementById('token').value;
if (!token) {
log('✗ 请先输入或加载 Token', 'error');
return;
}
await makeRequest(`${apiUrl}/cart`, {
method: 'GET',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
credentials: 'include'
});
}
// 测试 CORS 预检
async function testCORS() {
const apiUrl = document.getElementById('apiUrl').value;
log(`\n========== CORS 预检测试 ==========`, 'info');
log(`这个测试会发送 OPTIONS 请求`, 'info');
await makeRequest(`${apiUrl}/cart`, {
method: 'OPTIONS',
headers: {
'Origin': window.location.origin,
'Access-Control-Request-Method': 'GET',
'Access-Control-Request-Headers': 'authorization,content-type'
}
});
}
// 页面加载时执行
window.onload = function() {
showEnvInfo();
loadToken();
log('调试工具已就绪', 'success');
log('请按顺序测试各个接口,观察错误信息', 'info');
};
</script>
</body>
</html>