0eb0cf12fb
移除不再需要的测试脚本、调试页面和解决方案文档,包括: - 各种测试PHP文件(test.php, test_filters.php等) - VIP功能测试和调试页面(test_vip*.php, vip_debug_page.html等) - 数据库连接测试脚本(test_db_connection.php) - 解决方案文档(SOLUTIONS.md, VIP_*_Report.md)
571 lines
24 KiB
HTML
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('<')) {
|
|
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> |