addEventListener('fetch', event => { event.respondWith(handleRequest(event.request)); }); async function handleRequest(request) { const url = new URL(request.url); const cookie = request.headers.get('x-custom-cookie') || ''; // 从自定义请求头获取 cookie // 处理 CORS 预检请求 if (request.method === 'OPTIONS') { return new Response(null, { headers: { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'POST, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization, x-custom-cookie', // 添加自定义请求头 }, }); } // API路由处理 switch (url.pathname) { // 1. 通过图片URL识别 case '/api/recognize/url': if (request.method === 'POST') { return handleImageUrlRecognition(request); } break; // 2. 通过Base64识别 case '/api/recognize/base64': if (request.method === 'POST') { return handleBase64Recognition(request); } break; // 3. 通过图片文件识别 (原有的/recognize端点) case '/recognize': if (request.method === 'POST') { return handleFileRecognition(request); } break; // 添加代理路由 case '/proxy/upload': if (request.method === 'POST') { return handleProxyUpload(request); } break; // 返回前端界面 case '/': return new Response(getHTML(), { headers: { 'Content-Type': 'text/html' }, }); } return new Response('Not Found', { status: 404 }); } // 处理图片URL识别 async function handleImageUrlRecognition(request) { try { const { imageUrl } = await request.json(); const cookie = request.headers.get('x-custom-cookie'); if (!cookie || !imageUrl) { return new Response(JSON.stringify({ error: 'Missing cookie or imageUrl' }), { status: 400, headers: { 'Content-Type': 'application/json' }, }); } // 从cookie中提取token const tokenMatch = cookie.match(/token=([^;]+)/); if (!tokenMatch) { return new Response(JSON.stringify({ error: 'Invalid cookie format: missing token' }), { status: 400, headers: { 'Content-Type': 'application/json' }, }); } const token = tokenMatch[1]; // 下载图片 const imageResponse = await fetch(imageUrl); const imageBlob = await imageResponse.blob(); // 上传到QwenLM const formData = new FormData(); formData.append('file', imageBlob); const uploadResponse = await fetch('https://chat.qwenlm.ai/api/v1/files/', { method: 'POST', headers: { 'accept': 'application/json', 'authorization': `Bearer ${token}`, 'cookie': cookie }, body: formData, }); const uploadData = await uploadResponse.json(); if (!uploadData.id) throw new Error('File upload failed'); // 调用通用识别函数 return await recognizeImage(token, uploadData.id, request); } catch (error) { return new Response(JSON.stringify({ error: error.message || 'Internal Server Error' }), { status: 500, headers: { 'Content-Type': 'application/json' }, }); } } // 处理Base64识别 async function handleBase64Recognition(request) { try { const { base64Image } = await request.json(); const cookie = request.headers.get('x-custom-cookie'); if (!cookie || !base64Image) { return new Response(JSON.stringify({ error: 'Missing cookie or base64Image' }), { status: 400, headers: { 'Content-Type': 'application/json' }, }); } // 从cookie中提取token const tokenMatch = cookie.match(/token=([^;]+)/); if (!tokenMatch) { return new Response(JSON.stringify({ error: 'Invalid cookie format: missing token' }), { status: 400, headers: { 'Content-Type': 'application/json' }, }); } const token = tokenMatch[1]; // 转换Base64为Blob const imageData = base64Image.startsWith('data:') ? base64Image : 'data:image/png;base64,' + base64Image; const response = await fetch(imageData); const blob = await response.blob(); // 上传到QwenLM const formData = new FormData(); formData.append('file', blob); const uploadResponse = await fetch('https://chat.qwenlm.ai/api/v1/files/', { method: 'POST', headers: { 'accept': 'application/json', 'authorization': `Bearer ${token}`, 'cookie': cookie }, body: formData, }); const uploadData = await uploadResponse.json(); if (!uploadData.id) throw new Error('File upload failed'); // 调用通用识别函数 return await recognizeImage(token, uploadData.id, request); } catch (error) { return new Response(JSON.stringify({ error: error.message || 'Internal Server Error' }), { status: 500, headers: { 'Content-Type': 'application/json' }, }); } } // 处理文件识别 (原有功能) async function handleFileRecognition(request) { try { const { imageId } = await request.json(); const cookie = request.headers.get('x-custom-cookie') || ''; if (!cookie || !imageId) { return new Response(JSON.stringify({ error: 'Missing cookie or imageId' }), { status: 400, headers: { 'Content-Type': 'application/json' }, }); } // 从cookie中提取token const tokenMatch = cookie.match(/token=([^;]+)/); const token = tokenMatch ? tokenMatch[1] : ''; return await recognizeImage(token, imageId, request); } catch (error) { return new Response(JSON.stringify({ error: error.message || 'Internal Server Error' }), { status: 500, headers: { 'Content-Type': 'application/json' }, }); } } // 添加代理处理函数 async function handleProxyUpload(request) { try { const formData = await request.formData(); const cookie = request.headers.get('x-custom-cookie') || ''; // 从cookie中提取token const tokenMatch = cookie.match(/token=([^;]+)/); const token = tokenMatch ? tokenMatch[1] : ''; const response = await fetch('https://chat.qwenlm.ai/api/v1/files/', { method: 'POST', headers: { 'accept': 'application/json', 'authorization': `Bearer ${token}`, 'cookie': cookie }, body: formData, }); const data = await response.json(); return new Response(JSON.stringify(data), { headers: { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', }, }); } catch (error) { return new Response(JSON.stringify({ error: error.message || 'Proxy upload failed' }), { status: 500, headers: { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', }, }); } } // 通用的识别函数 async function recognizeImage(token, imageId, request) { const cookie = request.headers.get('x-custom-cookie') || ''; // 从请求头中获取高级模式状态和自定义prompt const advancedMode = request.headers.get('x-advanced-mode') === 'true'; // 解码自定义prompt let customPrompt = ''; try { const encodedPrompt = request.headers.get('x-custom-prompt'); if (encodedPrompt) { customPrompt = decodeURIComponent(atob(encodedPrompt)); } } catch (error) { console.error('Prompt解码错误:', error); } const defaultPrompt = '不要输出任何额外的解释或说明,禁止输出例如:识别内容、以上内容已严格按照要求进行格式化和转换等相关无意义的文字!' + '请识别图片中的内容,注意以下要求:\n' + '对于数学公式和普通文本:\n' + '1. 所有数学公式和数学符号都必须使用标准的LaTeX格式\n' + '2. 行内公式使用单个$符号包裹,如:$x^2$\n' + '3. 独立公式块使用两个$$符号包裹,如:$$\\sum_{i=1}^n i^2$$\n' + '4. 普通文本保持原样,不要使用LaTeX格式\n' + '5. 保持原文的段落格式和换行\n' + '6. 明显的换行使用\\n表示\n' + '7. 确保所有数学符号都被正确包裹在$或$$中\n\n' + '对于验证码图片:\n' + '1. 只输出验证码字符,不要加任何额外解释\n' + '2. 忽略干扰线和噪点\n' + '3. 注意区分相似字符,如0和O、1和l、2和Z等\n' + '4. 验证码通常为4-6位字母数字组合\n\n' + ''; const response = await fetch('https://chat.qwenlm.ai/api/chat/completions', { method: 'POST', headers: { 'Content-Type': 'application/json', 'User-Agent': 'PostmanRuntime/7.43.0', 'accept': '*/*', 'authorization': `Bearer ${token}`, 'cookie': cookie, }, body: JSON.stringify({ stream: false, chat_type: "t2t", model: 'qwen-max-latest', messages: [ { role: 'user', content: [ { type: 'text', text: advancedMode ? customPrompt : defaultPrompt, chat_type: "t2t" }, { type: 'image', image: imageId, chat_type: "t2t" }, ], }, ], session_id: '1', chat_id: '2', id: '3', }), }); const data = await response.json(); let result = data.choices[0]?.message?.content || '识别失败'; // 只在非高级模式下进行格式化处理 if (!advancedMode) { // 如果结果长度小于10且只包含字母数字,很可能是验证码 if (result.length <= 10 && /^[A-Za-z0-9]+$/.test(result)) { return new Response(JSON.stringify({ success: true, result: result.toUpperCase(), type: 'captcha' }), { headers: { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', }, }); } // 其他情况(数学公式和普通文本)的处理 result = result .replace(/\\(/g, '\\(') .replace(/\\)/g, '\\)') .replace(/\n{3,}/g, '\n\n') .replace(/([^\n])\n([^\n])/g, '$1\n$2') .replace(/\$\s+/g, '$') .replace(/\s+\$/g, '$') .replace(/\$\$/g, '$$') .trim(); } return new Response(JSON.stringify({ success: true, result: result, type: 'text' }), { headers: { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', }, }); } function getHTML() { const html = [ '', '', '', '', '', '', 'Qwen VL 智能识别系统', // 添加 MathJax 支持 '', '', '', '', '', '', '', '', ' 获取Cookie', '', '', ' ', ' ', ' ', '', '', '', '
', '

Qwen VL 智能识别系统

', '
基于通义千问大模型的多模态智能识别引擎
', '
', '📸', '
', '拖拽图片到这里,点击上传,或粘贴图片/Base64/URL
', '支持多种输入方式', '
', '
', '', '', '
', '', '', '
', '
', '', '
', '
', '
', '
', '识别结果', '', '
', '
', '
', '', '
', '

识别历史

', '
', '
', '', '
', '', '', '', '' ].join('\n'); return html; }