Files
leaudit-platform-frontend/app/routes/test.client-config.tsx
T

249 lines
11 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 客户端配置测试页面
* 用于验证Nginx代理和客户端ID检测是否正常工作
*/
import { json, type LoaderFunctionArgs } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
import { getApiConfig } from "~/config/api-config";
import { detectClientFromRequest, getRequestDebugInfo } from "~/utils/client-detection";
/**
* 服务器端loader函数 - 获取配置和调试信息
*/
export async function loader({ request }: LoaderFunctionArgs) {
// 获取客户端配置
const config = getApiConfig(request);
// 获取客户端检测信息
const detectedClientId = detectClientFromRequest(request);
// 获取调试信息
const debugInfo = getRequestDebugInfo(request);
// 获取当前URL信息
const url = new URL(request.url);
return json({
config,
detectedClientId,
debugInfo,
serverInfo: {
url: url.href,
host: url.host,
port: url.port,
pathname: url.pathname
},
timestamp: new Date().toISOString()
});
}
/**
* 客户端配置测试页面组件
*/
export default function ClientConfigTest() {
const data = useLoaderData<typeof loader>();
// 浏览器端检测客户端ID
const browserClientId = typeof window !== 'undefined' ? (() => {
const port = window.location.port;
const portToClient: Record<string, string> = {
'5174': 'client-a',
'5175': 'client-b',
'5176': 'client-c',
'5177': 'client-d'
};
return port && portToClient[port] ? portToClient[port] : 'unknown';
})() : 'server-side';
const browserPort = typeof window !== 'undefined' ? window.location.port : 'server-side';
return (
<div className="min-h-screen bg-gray-50 py-8">
<div className="max-w-4xl mx-auto px-4">
<div className="bg-white rounded-lg shadow-lg p-6">
<h1 className="text-3xl font-bold text-gray-900 mb-6">
🧪
</h1>
{/* 基本信息 */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8">
<div className="bg-blue-50 p-4 rounded-lg">
<h2 className="text-lg font-semibold text-blue-900 mb-3">📍 访</h2>
<div className="space-y-2 text-sm">
<div><strong>URL:</strong> {data.serverInfo.url}</div>
<div><strong>:</strong> {data.serverInfo.host}</div>
<div><strong>:</strong> {data.serverInfo.port || '默认端口'}</div>
<div><strong>:</strong> {data.serverInfo.pathname}</div>
<div><strong>:</strong> {browserPort}</div>
</div>
</div>
<div className="bg-green-50 p-4 rounded-lg">
<h2 className="text-lg font-semibold text-green-900 mb-3">🎯 </h2>
<div className="space-y-2 text-sm">
<div><strong>:</strong>
<span className={`ml-2 px-2 py-1 rounded text-xs ${
data.detectedClientId !== 'main' ? 'bg-green-200 text-green-800' : 'bg-yellow-200 text-yellow-800'
}`}>
{data.detectedClientId}
</span>
</div>
<div><strong>:</strong>
<span className={`ml-2 px-2 py-1 rounded text-xs ${
browserClientId !== 'unknown' ? 'bg-green-200 text-green-800' : 'bg-yellow-200 text-yellow-800'
}`}>
{browserClientId}
</span>
</div>
</div>
</div>
</div>
{/* Nginx请求头信息 */}
<div className="mb-8">
<h2 className="text-lg font-semibold text-gray-900 mb-3">🔍 Nginx请求头信息</h2>
<div className="bg-gray-50 p-4 rounded-lg">
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 text-sm">
<div>
<strong>X-Client-ID:</strong>
<span className={`ml-2 px-2 py-1 rounded text-xs ${
data.debugInfo.clientId ? 'bg-green-200 text-green-800' : 'bg-red-200 text-red-800'
}`}>
{data.debugInfo.clientId || '未检测到'}
</span>
</div>
<div>
<strong>X-Original-Port:</strong>
<span className={`ml-2 px-2 py-1 rounded text-xs ${
data.debugInfo.originalPort ? 'bg-green-200 text-green-800' : 'bg-red-200 text-red-800'
}`}>
{data.debugInfo.originalPort || '未检测到'}
</span>
</div>
<div>
<strong>X-Forwarded-Port:</strong>
<span className="ml-2 px-2 py-1 rounded text-xs bg-gray-200 text-gray-800">
{data.debugInfo.forwardedPort || '未设置'}
</span>
</div>
<div>
<strong>X-Real-IP:</strong>
<span className="ml-2 px-2 py-1 rounded text-xs bg-gray-200 text-gray-800">
{data.debugInfo.realIp || '未设置'}
</span>
</div>
</div>
</div>
</div>
{/* 当前配置信息 */}
<div className="mb-8">
<h2 className="text-lg font-semibold text-gray-900 mb-3"> API配置</h2>
<div className="bg-gray-50 p-4 rounded-lg">
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 text-sm">
<div><strong>Base URL:</strong> {data.config.baseUrl}</div>
<div><strong>Upload URL:</strong> {data.config.uploadUrl}</div>
<div><strong>Document URL:</strong> {data.config.documentUrl}</div>
<div><strong>OAuth Server:</strong> {data.config.oauth.serverUrl}</div>
<div><strong>OAuth Redirect:</strong> {data.config.oauth.redirectUri}</div>
<div><strong>OAuth Client ID:</strong> {data.config.oauth.clientId.substring(0, 20)}...</div>
</div>
</div>
</div>
{/* 状态检查 */}
<div className="mb-8">
<h2 className="text-lg font-semibold text-gray-900 mb-3"> </h2>
<div className="space-y-3">
<div className="flex items-center space-x-3">
<div className={`w-3 h-3 rounded-full ${
data.debugInfo.clientId ? 'bg-green-500' : 'bg-red-500'
}`}></div>
<span className={data.debugInfo.clientId ? 'text-green-700' : 'text-red-700'}>
{data.debugInfo.clientId ? '✅ Nginx X-Client-ID 传递正常' : '❌ Nginx X-Client-ID 未传递'}
</span>
</div>
<div className="flex items-center space-x-3">
<div className={`w-3 h-3 rounded-full ${
data.detectedClientId !== 'main' ? 'bg-green-500' : 'bg-yellow-500'
}`}></div>
<span className={data.detectedClientId !== 'main' ? 'text-green-700' : 'text-yellow-700'}>
{data.detectedClientId !== 'main' ? '✅ 服务器端客户端检测成功' : '⚠️ 服务器端使用默认配置'}
</span>
</div>
<div className="flex items-center space-x-3">
<div className={`w-3 h-3 rounded-full ${
browserClientId !== 'unknown' ? 'bg-green-500' : 'bg-yellow-500'
}`}></div>
<span className={browserClientId !== 'unknown' ? 'text-green-700' : 'text-yellow-700'}>
{browserClientId !== 'unknown' ? '✅ 浏览器端客户端检测成功' : '⚠️ 浏览器端使用默认配置'}
</span>
</div>
<div className="flex items-center space-x-3">
<div className={`w-3 h-3 rounded-full ${
data.config.baseUrl.includes(data.detectedClientId.replace('client-', '517')) ? 'bg-green-500' : 'bg-yellow-500'
}`}></div>
<span className={data.config.baseUrl.includes(data.detectedClientId.replace('client-', '517')) ? 'text-green-700' : 'text-yellow-700'}>
{data.config.baseUrl.includes(data.detectedClientId.replace('client-', '517')) ? '✅ 配置匹配正确' : '⚠️ 配置可能不匹配'}
</span>
</div>
</div>
</div>
{/* 调试信息 */}
<div className="mb-8">
<h2 className="text-lg font-semibold text-gray-900 mb-3">🔧 </h2>
<details className="bg-gray-50 p-4 rounded-lg">
<summary className="cursor-pointer text-sm font-medium text-gray-700 mb-2">
</summary>
<pre className="text-xs bg-white p-3 rounded border overflow-auto">
{JSON.stringify({
serverData: data,
browserInfo: {
clientId: browserClientId,
port: browserPort,
userAgent: typeof window !== 'undefined' ? navigator.userAgent : 'server-side'
}
}, null, 2)}
</pre>
</details>
</div>
{/* 测试链接 */}
<div>
<h2 className="text-lg font-semibold text-gray-900 mb-3">🔗 </h2>
<div className="grid grid-cols-2 md:grid-cols-4 gap-3">
{[
{ port: '5174', client: 'client-a', name: '客户端A' },
{ port: '5175', client: 'client-b', name: '客户端B' },
{ port: '5176', client: 'client-c', name: '客户端C' },
{ port: '5177', client: 'client-d', name: '客户端D' }
].map(({ port, client, name }) => (
<a
key={port}
href={`http://localhost:${port}/test/client-config`}
className={`block p-3 rounded-lg text-center text-sm font-medium transition-colors ${
browserPort === port
? 'bg-blue-600 text-white'
: 'bg-blue-100 text-blue-700 hover:bg-blue-200'
}`}
>
{name}<br/>
<span className="text-xs opacity-75">:{port}</span>
</a>
))}
</div>
</div>
<div className="mt-6 text-xs text-gray-500">
: {data.timestamp}
</div>
</div>
</div>
</div>
);
}