|
注册账号,享受无广告的清爽界面!
您需要 登录 才可以下载或查看,没有账号?注册
×
key:
另外安利下我的检测工具:https://sfchecker.elfmaid.me/
也可以自建一个哈:addEventListener('fetch', function(event) {
event.respondWith(handleRequest(event.request));
});
function handleRequest(request) {
if (request.method === 'OPTIONS') {
return handleOptions(request);
}
if (request.method === 'POST') {
return handlePost(request);
}
return new Response(getHtmlContent(), {
headers: {
'content-type': 'text/html;charset=UTF-8',
'Access-Control-Allow-Origin': '*',
'Cache-Control': 'no-cache',
},
});
}
function handlePost(request) {
return request.json()
.then(function(data) {
var tokens = data.tokens || [];
if (!tokens.length) {
throw new Error('No tokens provided');
}
return Promise.all(tokens.map(function(token) {
return checkToken(token);
}));
})
.then(function(results) {
return new Response(JSON.stringify(results), {
headers: {
'content-type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Cache-Control': 'no-cache',
},
});
})
.catch(function(error) {
return new Response(JSON.stringify({
error: error.message || 'Unknown error occurred'
}), {
status: 400,
headers: {
'content-type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Cache-Control': 'no-cache',
},
});
});
}
function checkToken(token) {
var checkUrl = 'https://api.siliconflow.cn/v1/chat/completions';
var balanceUrl = 'https://api.siliconflow.cn/v1/user/info';
var requestOptions = {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + token,
'Content-Type': 'application/json',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36',
'Accept': 'application/json',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'cross-site'
},
body: JSON.stringify({
"model": "Qwen/Qwen2.5-72B-Instruct",
"messages": [{"role": "user", "content": "hi"}],
"max_tokens": 100,
"stream": false
})
};
return fetch(checkUrl, requestOptions)
.then(function(response) {
if (response.ok) {
return fetch(balanceUrl, {
headers: {
'Authorization': 'Bearer ' + token,
'Accept': 'application/json',
'Accept-Language': 'zh-CN,zh;q=0.9'
}
})
.then(function(balanceResponse) {
if (!balanceResponse.ok) {
throw new Error('Balance check failed');
}
return balanceResponse.json();
})
.then(function(balanceData) {
return {
token: token,
isValid: true,
balance: balanceData.data.totalBalance
};
})
.catch(function() {
return {
token: token,
isValid: true,
balance: '获取余额失败'
};
});
}
return response.json()
.then(function(errorData) {
return {
token: token,
isValid: false,
message: errorData.message || '验证失败'
};
})
.catch(function() {
return {
token: token,
isValid: false,
message: '验证请求失败'
};
});
})
.catch(function(error) {
return {
token: token,
isValid: false,
message: '网络请求失败: ' + error.message
};
});
}
function handleOptions(request) {
return new Response(null, {
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
'Access-Control-Max-Age': '86400',
},
});
}
function getHtmlContent() {
return `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>硅基流动Token检测工具</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🚀</text></svg>">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&family=JetBrains+Mono:wght@400;600&display=swap" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.net.min.js"></script>
<style>
:root {
--primary: #64ffda;
--bg-dark: #0a192f;
--text: #ccd6f6;
--error: #ff3b30;
--success: #64ffda;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
background-color: var(--bg-dark);
color: var(--text);
line-height: 1.6;
min-height: 100vh;
overflow-x: hidden;
}
#vanta-canvas {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 0;
}
.container {
position: relative;
z-index: 1;
max-width: 1000px;
margin: 0 auto;
padding: 40px 20px;
}
.glass-panel {
background: rgba(10, 25, 47, 0.7);
backdrop-filter: blur(10px);
border-radius: 24px;
padding: 40px;
border: 1px solid rgba(100, 255, 218, 0.1);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
}
h1 {
font-size: 2.5rem;
text-align: center;
margin-bottom: 40px;
color: var(--primary);
text-shadow: 0 0 20px rgba(100, 255, 218, 0.3);
font-weight: 600;
}
.input-group {
margin-bottom: 30px;
}
textarea {
width: 100%;
height: 200px;
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(100, 255, 218, 0.2);
border-radius: 12px;
padding: 20px;
color: var(--text);
font-family: 'JetBrains Mono', monospace;
font-size: 14px;
resize: vertical;
transition: all 0.3s ease;
}
textarea:focus {
outline: none;
border-color: var(--primary);
box-shadow: 0 0 20px rgba(100, 255, 218, 0.1);
}
.button-container {
text-align: center;
margin: 30px 0;
}
button {
background: transparent;
color: var(--primary);
border: 2px solid var(--primary);
padding: 12px 30px;
border-radius: 8px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
button:hover {
background: rgba(100, 255, 218, 0.1);
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(100, 255, 218, 0.2);
}
button:disabled {
opacity: 0.6;
cursor: not-allowed;
transform: none;
}
.progress-container {
margin: 20px 0;
text-align: center;
display: none;
}
.progress-bar {
width: 100%;
height: 6px;
background: rgba(255, 255, 255, 0.1);
border-radius: 3px;
overflow: hidden;
margin-bottom: 10px;
}
.progress {
width: 0%;
height: 100%;
background: linear-gradient(90deg, var(--primary) 0%, #4facfe 100%);
transition: width 0.3s ease;
border-radius: 3px;
}
.progress-text {
font-size: 14px;
color: var(--text);
}
.results {
margin-top: 40px;
}
.results h2 {
font-size: 1.5rem;
color: var(--text);
margin-bottom: 20px;
display: flex;
align-items: center;
gap: 10px;
}
.results h2::before {
content: '';
display: block;
width: 4px;
height: 24px;
background: var(--primary);
border-radius: 2px;
}
.results-content {
background: rgba(255, 255, 255, 0.03);
border-radius: 12px;
padding: 20px;
margin-bottom: 20px;
border: 1px solid rgba(255, 255, 255, 0.1);
}
#validResults {
font-family: 'JetBrains Mono', monospace;
white-space: pre-wrap;
color: var(--success);
word-break: break-all;
}
.invalid-token {
background: rgba(255, 59, 48, 0.1);
border-radius: 8px;
padding: 15px;
margin-bottom: 15px;
border-left: 4px solid var(--error);
animation: slideIn 0.3s ease-out;
}
.loader {
display: inline-block;
width: 20px;
height: 20px;
border: 3px solid rgba(100, 255, 218, 0.3);
border-radius: 50%;
border-top-color: var(--primary);
animation: spin 1s linear infinite;
margin-right: 10px;
vertical-align: middle;
}
.toast {
position: fixed;
bottom: 20px;
right: 20px;
padding: 12px 24px;
background: rgba(100, 255, 218, 0.9);
color: var(--bg-dark);
border-radius: 8px;
font-weight: 600;
transform: translateY(100px);
opacity: 0;
transition: all 0.3s ease;
z-index: 1000;
}
.toast.show {
transform: translateY(0);
opacity: 1;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
@keyframes slideIn {
from {
opacity: 0;
transform: translateX(-10px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@media (max-width: 768px) {
.container {
padding: 20px;
}
.glass-panel {
padding: 20px;
}
h1 {
font-size: 2rem;
}
button {
width: 100%;
}
}
</style>
</head>
<body>
<div id="vanta-canvas"></div>
<div class="container">
<div class="glass-panel">
<h1>硅基流动Token检测工具</h1>
<div class="input-group">
<textarea id="tokens" placeholder="请在此输入sk token,每行一个"></textarea>
</div>
<div class="progress-container">
<div class="progress-bar">
<div class="progress"></div>
</div>
<div class="progress-text">检测进度: <span id="progress-percentage">0</span>%</div>
</div>
<div class="button-container">
<button id="checkButton" onclick="checkTokens()">开始检测</button>
</div>
<div class="results">
<h2>有效账号</h2>
<div id="validResults" class="results-content"></div>
<button id="copyButton" onclick="copyValidTokens()" style="display: none;">复制有效账号</button>
<h2>无效账号</h2>
<div id="invalidResults" class="results-content"></div>
</div>
</div>
</div>
<div id="toast" class="toast"></div>
<script>
window.addEventListener('DOMContentLoaded', function() {
VANTA.NET({
el: "#vanta-canvas",
mouseControls: true,
touchControls: true,
gyroControls: false,
minHeight: 200.00,
minWidth: 200.00,
scale: 1.00,
scaleMobile: 1.00,
color: 0x64ffda,
backgroundColor: 0x0a192f,
points: 10.00,
maxDistance: 20.00,
spacing: 20.00
});
});
function showToast(message, duration) {
var toast = document.getElementById('toast');
toast.textContent = message;
toast.classList.add('show');
setTimeout(function() {
toast.classList.remove('show');
}, duration || 3000);
}
function checkTokens() {
var tokensTextarea = document.getElementById('tokens');
var checkButton = document.getElementById('checkButton');
var validResults = document.getElementById('validResults');
var invalidResults = document.getElementById('invalidResults');
var copyButton = document.getElementById('copyButton');
var progressContainer = document.querySelector('.progress-container');
var progressBar = document.querySelector('.progress');
var progressText = document.getElementById('progress-percentage');
var tokens = tokensTextarea.value.split('\\n').filter(function(token) {
return token.trim() !== '';
});
if (!tokens.length) {
showToast('请输入至少一个token', 2000);
return;
}
checkButton.disabled = true;
checkButton.innerHTML = '<span class="loader"></span>检测中...';
validResults.textContent = '';
invalidResults.innerHTML = '';
copyButton.style.display = 'none';
progressContainer.style.display = 'block';
progressBar.style.width = '0%';
progressText.textContent = '0';
var completed = 0;
var results = [];
function processTokens(tokens, batchSize) {
var batches = [];
for (var i = 0; i < tokens.length; i += batchSize) {
batches.push(tokens.slice(i, i + batchSize));
}
return batches.reduce(function(promise, batch) {
return promise.then(function() {
return Promise.all(batch.map(function(token) {
return fetch(window.location.href, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ tokens: [token] })
})
.then(function(response) { return response.json(); })
.then(function(result) {
completed++;
var progress = Math.round((completed / tokens.length) * 100);
progressBar.style.width = progress + '%';
progressText.textContent = progress;
return result[0];
});
}));
}).then(function(batchResults) {
results = results.concat(batchResults);
updateResults(results);
});
}, Promise.resolve());
}
function updateResults(results) {
var validTokens = results.filter(function(r) {
return r.isValid;
}).map(function(r) {
return r.token + ' (余额: ' + r.balance + ')';
});
var invalidTokens = results.filter(function(r) {
return !r.isValid;
});
validResults.textContent = validTokens.join('\\n');
invalidResults.innerHTML = '';
invalidTokens.forEach(function(result) {
var div = document.createElement('div');
div.className = 'invalid-token';
div.innerHTML =
'<div class="invalid-token-content">' +
'<div class="invalid-token-token">' + result.token + '</div>' +
'<div class="invalid-token-message">' + result.message + '</div>' +
'</div>';
invalidResults.appendChild(div);
});
if (validTokens.length > 0) {
copyButton.style.display = 'block';
}
}
processTokens(tokens, 3)
.then(function() {
showToast('检测完成!', 2000);
})
.catch(function(error) {
showToast('检测过程出错: ' + error.message, 3000);
})
.finally(function() {
checkButton.disabled = false;
checkButton.textContent = '开始检测';
progressContainer.style.display = 'none';
});
}
function copyValidTokens() {
var validResults = document.getElementById('validResults');
var tokens = validResults.textContent.split('\\n').map(function(line) {
return line.split(' ')[0];
});
var textArea = document.createElement('textarea');
textArea.value = tokens.join('\\n');
document.body.appendChild(textArea);
textArea.select();
document.execCommand('copy');
document.body.removeChild(textArea);
showToast('有效账号已复制到剪贴板', 2000);
}
</script>
</body>
</html>`;
}
|
|