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
carwash_order/test/test_vip_ajax.html
T
wsh5485 0eb0cf12fb chore: 删除测试和调试相关文件
移除不再需要的测试脚本、调试页面和解决方案文档,包括:
- 各种测试PHP文件(test.php, test_filters.php等)
- VIP功能测试和调试页面(test_vip*.php, vip_debug_page.html等)
- 数据库连接测试脚本(test_db_connection.php)
- 解决方案文档(SOLUTIONS.md, VIP_*_Report.md)
2025-12-05 01:38:06 +08:00

571 lines
24 KiB
HTML

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>VIP客户AJAX请求测试</title>
<style>
body {
font-family: Arial, sans-serif;
line-height: 1.6;
max-width: 800px;
margin: 0 auto;
padding: 20px;
color: #333;
}
h1, h2, h3 {
color: #2c3e50;
}
.container {
background: #f9f9f9;
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
}
.test-button {
background: #3498db;
color: white;
border: none;
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
margin-right: 10px;
margin-bottom: 10px;
}
.test-button:hover {
background: #2980b9;
}
.info-box {
background: #e8f4fc;
border-left: 4px solid #3498db;
padding: 15px;
margin: 15px 0;
}
.success-box {
background: #e8f8f5;
border-left: 4px solid #27ae60;
padding: 15px;
margin: 15px 0;
}
.error-box {
background: #ffeaea;
border-left: 4px solid #e74c3c;
padding: 15px;
margin: 15px 0;
}
.warning-box {
background: #fff8e1;
border-left: 4px solid #ffc107;
padding: 15px;
margin: 15px 0;
}
.code-box {
background: #f5f5f5;
padding: 15px;
border-radius: 5px;
overflow-x: auto;
font-family: monospace;
white-space: pre-wrap;
}
.log-box {
background: #2c3e50;
color: #ecf0f1;
padding: 15px;
border-radius: 5px;
max-height: 300px;
overflow-y: auto;
font-family: monospace;
font-size: 14px;
}
.log-info { color: #3498db; }
.log-success { color: #27ae60; }
.log-error { color: #e74c3c; }
.log-warning { color: #f39c12; }
label {
display: block;
margin: 10px 0 5px;
}
input[type="text"] {
padding: 8px;
width: 100%;
box-sizing: border-box;
margin-bottom: 10px;
}
.result-box {
margin-top: 20px;
padding: 15px;
border: 1px solid #ddd;
border-radius: 5px;
background: #fafafa;
}
</style>
</head>
<body>
<h1>VIP客户AJAX请求测试</h1>
<div class="container">
<h2>测试设置</h2>
<div class="info-box">
<p>这个页面将使用不同的方法测试VIP客户数据加载,帮助诊断为什么在主应用中显示"数据库中VIP客户数: 0"。</p>
</div>
<label for="api-url">API URL路径:</label>
<input type="text" id="api-url" value="get_vip_customers.php" placeholder="输入API的URL路径">
<button class="test-button" onclick="testFetch()">测试使用fetch()加载</button>
<button class="test-button" onclick="testXHR()">测试使用XMLHttpRequest加载</button>
<button class="test-button" onclick="testDirectLink()">直接访问API链接</button>
<button class="test-button" onclick="testRelativePaths()">测试所有相对路径</button>
<button class="test-button" onclick="testInNewContext()">在新上下文中测试</button>
</div>
<div class="container">
<h2>测试结果</h2>
<div id="result" class="result-box">
<p>点击上方按钮开始测试...</p>
</div>
<h3>调试日志</h3>
<div id="log" class="log-box">
[系统] 就绪
</div>
</div>
<div class="container">
<h2>环境信息</h2>
<p>当前页面URL: <span id="current-url"></span></p>
<p>当前路径: <span id="current-path"></span></p>
</div>
<div class="container">
<h2>常见问题解决方案</h2>
<h3>1. 路径问题</h3>
<div class="info-box">
<p>如果测试显示路径问题,可以尝试以下修复:</p>
<pre class="code-box">// 修改index.php中的fetch调用
fetch('/carwashorder/carwash_order/get_vip_customers.php') // 使用绝对路径</pre>
</div>
<h3>2. JSON解析问题</h3>
<div class="info-box">
<p>如果JSON解析失败,可以修改错误处理以捕获更多信息:</p>
<pre class="code-box">// 在loadVIPCustomers函数中添加更详细的错误处理
try {
const data = JSON.parse(text);
console.log('解析成功:', data);
} catch (parseError) {
console.error('JSON解析失败:', parseError);
console.error('原始响应文本:', text);
// 尝试诊断文本内容
if (text.includes('&lt;')) {
console.error('响应可能包含HTML内容而非纯JSON');
}
}</pre>
</div>
<h3>3. 网络请求被阻止</h3>
<div class="info-box">
<p>检查浏览器控制台中的网络请求,确认请求是否被阻止或重定向。</p>
</div>
</div>
<script>
// 显示环境信息
document.getElementById('current-url').textContent = window.location.href;
document.getElementById('current-path').textContent = window.location.pathname;
// 日志函数
function log(type, message) {
const logBox = document.getElementById('log');
const timestamp = new Date().toLocaleTimeString();
const logClass = 'log-' + type;
logBox.innerHTML += `\n[${timestamp}] <span class="${logClass}">${message}</span>`;
logBox.scrollTop = logBox.scrollHeight;
}
// 显示结果
function showResult(title, content, type = 'info') {
const resultBox = document.getElementById('result');
let boxClass = '';
let titleColor = '#3498db';
switch(type) {
case 'success':
boxClass = 'success-box';
titleColor = '#27ae60';
break;
case 'error':
boxClass = 'error-box';
titleColor = '#e74c3c';
break;
case 'warning':
boxClass = 'warning-box';
titleColor = '#f39c12';
break;
default:
boxClass = 'info-box';
}
resultBox.innerHTML = `
<div class="${boxClass}">
<h3 style="margin-top: 0; color: ${titleColor};">${title}</h3>
<div>${content}</div>
</div>
`;
}
// 测试fetch请求
function testFetch() {
const apiUrl = document.getElementById('api-url').value;
log('info', `开始使用fetch()测试URL: ${apiUrl}`);
showResult('测试进行中', '正在发送fetch请求...');
fetch(apiUrl)
.then(response => {
log('info', `响应状态: ${response.status} ${response.statusText}`);
if (!response.ok) {
throw new Error(`HTTP错误! 状态: ${response.status}`);
}
return response.text();
})
.then(text => {
log('info', '接收到响应文本');
log('info', `响应文本长度: ${text.length} 字符`);
// 显示原始响应的前500个字符
const preview = text.length > 500 ? text.substring(0, 500) + '...' : text;
try {
const data = JSON.parse(text);
log('success', 'JSON解析成功');
let resultContent = `
<p><strong>原始响应预览:</strong></p>
<pre class="code-box">${preview}</pre>
<p><strong>解析结果:</strong></p>
`;
if (Array.isArray(data)) {
resultContent += `
<p>返回的是数组,包含 <strong>${data.length}</strong> 个VIP客户</p>
`;
if (data.length > 0) {
resultContent += `
<p><strong>第一个VIP客户:</strong></p>
<pre class="code-box">${JSON.stringify(data[0], null, 2)}</pre>
`;
}
} else if (typeof data === 'object' && data !== null) {
resultContent += `
<p>返回的是对象</p>
<pre class="code-box">${JSON.stringify(data, null, 2)}</pre>
`;
} else {
resultContent += `
<p>返回的数据类型: ${typeof data}</p>
`;
}
showResult('fetch请求成功', resultContent, 'success');
} catch (parseError) {
log('error', `JSON解析失败: ${parseError.message}`);
// 检查是否包含HTML标签
const hasHtml = text.includes('<');
const hasError = text.includes('error') || text.includes('Error');
let diagnosticInfo = '';
if (hasHtml) {
diagnosticInfo += '<p><strong>警告:</strong> 响应中可能包含HTML内容而非纯JSON</p>';
}
if (hasError) {
diagnosticInfo += '<p><strong>警告:</strong> 响应中可能包含错误信息</p>';
}
showResult('fetch请求成功但JSON解析失败', `
<p><strong>原始响应:</strong></p>
<pre class="code-box">${preview}</pre>
<p><strong>错误信息:</strong> ${parseError.message}</p>
${diagnosticInfo}
`, 'error');
}
})
.catch(error => {
log('error', `fetch请求失败: ${error.message}`);
showResult('fetch请求失败', `
<p><strong>错误信息:</strong> ${error.message}</p>
<p>请检查URL路径是否正确或服务器是否正常运行。</p>
`, 'error');
});
}
// 测试XMLHttpRequest
function testXHR() {
const apiUrl = document.getElementById('api-url').value;
log('info', `开始使用XMLHttpRequest测试URL: ${apiUrl}`);
showResult('测试进行中', '正在发送XHR请求...');
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE) {
log('info', `XHR响应状态: ${xhr.status} ${xhr.statusText}`);
if (xhr.status === 200) {
const text = xhr.responseText;
log('info', `XHR响应文本长度: ${text.length} 字符`);
const preview = text.length > 500 ? text.substring(0, 500) + '...' : text;
try {
const data = JSON.parse(text);
log('success', 'XHR JSON解析成功');
let resultContent = `
<p><strong>原始响应预览:</strong></p>
<pre class="code-box">${preview}</pre>
<p><strong>解析结果:</strong></p>
`;
if (Array.isArray(data)) {
resultContent += `
<p>返回的是数组,包含 <strong>${data.length}</strong> 个VIP客户</p>
`;
} else if (typeof data === 'object' && data !== null) {
resultContent += `
<p>返回的是对象</p>
<pre class="code-box">${JSON.stringify(data, null, 2)}</pre>
`;
}
showResult('XHR请求成功', resultContent, 'success');
} catch (parseError) {
log('error', `XHR JSON解析失败: ${parseError.message}`);
showResult('XHR请求成功但JSON解析失败', `
<p><strong>原始响应:</strong></p>
<pre class="code-box">${preview}</pre>
<p><strong>错误信息:</strong> ${parseError.message}</p>
`, 'error');
}
} else {
log('error', `XHR请求失败: 状态 ${xhr.status}`);
showResult('XHR请求失败', `
<p><strong>错误状态:</strong> ${xhr.status} ${xhr.statusText}</p>
<p><strong>响应文本:</strong></p>
<pre class="code-box">${xhr.responseText}</pre>
`, 'error');
}
}
};
xhr.onerror = function() {
log('error', 'XHR网络错误');
showResult('XHR网络错误', `
<p>无法建立网络连接。请检查URL是否正确或服务器是否正常运行。</p>
`, 'error');
};
xhr.open('GET', apiUrl, true);
xhr.send();
}
// 直接访问API链接
function testDirectLink() {
const apiUrl = document.getElementById('api-url').value;
window.open(apiUrl, '_blank');
log('info', `已在新窗口打开API链接: ${apiUrl}`);
showResult('API直接访问', `
<p>已在新窗口打开API链接。请查看新窗口中的响应内容,确认是否返回了有效的JSON数据。</p>
`, 'info');
}
// 测试所有可能的相对路径
function testRelativePaths() {
const pathsToTest = [
'get_vip_customers.php',
'./get_vip_customers.php',
'../carwash_order/get_vip_customers.php',
'/carwashorder/carwash_order/get_vip_customers.php'
];
log('info', '开始测试多个可能的相对路径');
showResult('路径测试进行中', `正在测试 ${pathsToTest.length} 个可能的路径...`);
let results = [];
let completedTests = 0;
pathsToTest.forEach((path, index) => {
setTimeout(() => {
fetch(path)
.then(response => response.ok ? response.text() : Promise.reject(response.status))
.then(text => {
try {
const data = JSON.parse(text);
results.push({
path: path,
status: 'success',
count: Array.isArray(data) ? data.length : null,
error: null
});
log('success', `路径 ${path} 测试成功`);
} catch (e) {
results.push({
path: path,
status: 'parse-error',
count: null,
error: e.message
});
log('warning', `路径 ${path} 返回数据但解析失败: ${e.message}`);
}
})
.catch(error => {
results.push({
path: path,
status: 'error',
count: null,
error: typeof error === 'number' ? `HTTP ${error}` : error.message
});
log('error', `路径 ${path} 测试失败: ${error}`);
})
.finally(() => {
completedTests++;
if (completedTests === pathsToTest.length) {
displayPathResults(results);
}
});
}, index * 500); // 错开请求,避免同时发送
});
}
// 显示路径测试结果
function displayPathResults(results) {
let html = '<h4>路径测试结果</h4><table border="1" cellpadding="5" cellspacing="0" width="100%"><tr><th>路径</th><th>状态</th><th>VIP客户数量</th><th>错误信息</th></tr>';
results.forEach(result => {
let statusColor = '#e74c3c';
let statusText = '失败';
if (result.status === 'success') {
statusColor = '#27ae60';
statusText = '成功';
} else if (result.status === 'parse-error') {
statusColor = '#f39c12';
statusText = '数据解析失败';
}
html += `<tr>
<td>${result.path}</td>
<td style="color: ${statusColor};">${statusText}</td>
<td>${result.count !== null ? result.count : '-'}</td>
<td>${result.error || '-'}</td>
</tr>`;
});
html += '</table>';
// 找出成功的路径
const successPaths = results.filter(r => r.status === 'success');
if (successPaths.length > 0) {
html += '<div class="success-box" style="margin-top: 10px;">
<p><strong>推荐路径:</strong></p>
<ul>
' + successPaths.map(p => `<li>${p.path}</li>`).join('') + '
</ul>
</div>';
}
showResult('路径测试完成', html, 'info');
}
// 在新上下文中测试(模拟主应用环境)
function testInNewContext() {
log('info', '在新上下文中测试,模拟主应用环境');
showResult('新上下文测试', '请查看浏览器控制台的详细日志...', 'info');
// 模拟主应用的加载环境
console.log('===== 开始模拟主应用环境 =====');
// 创建一个测试的window对象
const testContext = {};
// 模拟loadVIPCustomers函数
function simulateLoadVIPCustomers() {
console.log('模拟loadVIPCustomers调用...');
return fetch(document.getElementById('api-url').value)
.then(response => {
console.log('模拟响应状态:', response.status);
return response.text();
})
.then(text => {
console.log('模拟响应文本:', text);
try {
const data = JSON.parse(text);
testContext.allVIPCustomers = data;
console.log('模拟数据存储成功:', testContext.allVIPCustomers);
console.log('VIP客户数量:', Array.isArray(data) ? data.length : '非数组');
// 模拟匹配逻辑
simulateCheckPhoneForVIP('18699627661');
return data;
} catch (e) {
console.error('模拟JSON解析失败:', e);
return null;
}
})
.catch(error => {
console.error('模拟加载失败:', error);
return null;
});
}
// 模拟checkPhoneForVIP函数
function simulateCheckPhoneForVIP(phone) {
console.log('\n模拟checkPhoneForVIP调用,搜索手机号:', phone);
if (!testContext.allVIPCustomers) {
console.error('错误: VIP数据未加载');
return null;
}
// 标准化手机号
const normalizedPhone = phone.replace(/\D/g, '');
console.log('标准化后的手机号:', normalizedPhone);
console.log('VIP客户总数:', Array.isArray(testContext.allVIPCustomers) ? testContext.allVIPCustomers.length : '非数组');
// 简单匹配逻辑
if (Array.isArray(testContext.allVIPCustomers)) {
const matched = testContext.allVIPCustomers.find(vip =>
vip.phone === phone ||
vip.phone.replace(/\D/g, '') === normalizedPhone
);
if (matched) {
console.log('找到匹配的VIP客户:', matched.customer_name, matched.phone);
} else {
console.log('未找到匹配的VIP客户');
}
}
}
// 执行测试
simulateLoadVIPCustomers().then(() => {
console.log('===== 模拟测试完成 =====');
showResult('新上下文测试完成', `
<p>请查看浏览器控制台中的详细测试日志。</p>
<p>该测试模拟了主应用中加载VIP数据和搜索的完整过程。</p>
`, 'success');
});
}
</script>
</body>
</html>