Download public/js/main.js from hijnu/exec: direct link, hf CLI and curl.
- Browser
- Download file 8.06 kB
-
https://huggingface.co/spaces/hijnu/exec/resolve/main/public/js/main.js
- Command line
-
hf download hf://spaces/hijnu/exec/public/js/main.js
-
curl -L -o main.js https://huggingface.co/spaces/hijnu/exec/resolve/main/public/js/main.js
8.06 kB
| const commandInput = document.getElementById('command'); | |
| const output = document.getElementById('output'); | |
| const history = document.getElementById('history'); | |
| const executeButton = document.getElementById('executeButton'); | |
| const loadingIndicator = document.getElementById('loadingIndicator'); | |
| commandInput.addEventListener('keypress', function (event) { | |
| if (event.key === 'Enter') { | |
| executeCommand(); | |
| } | |
| }); | |
| async function executeCommand() { | |
| const command = commandInput.value; | |
| if (!command.trim()) return; | |
| showLoading(true); | |
| clearOutput(); | |
| appendToOutput('$ ' + command, 'text-blue-400'); | |
| appendToOutput('正在执行命令...', 'text-yellow-400'); | |
| try { | |
| let response = await fetch('/api/execute', { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| 'Authorization': `Bearer ${localStorage.getItem('token')}` | |
| }, | |
| body: JSON.stringify({ command }) | |
| }); | |
| if (response.status === 403) { | |
| const refreshed = await refreshToken(); | |
| if (refreshed) { | |
| response = await fetch('/api/execute', { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| 'Authorization': `Bearer ${localStorage.getItem('token')}` | |
| }, | |
| body: JSON.stringify({ command }) | |
| }); | |
| } else { | |
| throw new Error('Token 刷新失败'); | |
| } | |
| } | |
| if (!response.ok) { | |
| throw new Error(`HTTP error! status: ${response.status}`); | |
| } | |
| const data = await response.json(); | |
| clearOutput(); | |
| appendToOutput('$ ' + command, 'text-blue-400'); | |
| appendToOutput(data.output || data.error || '命令执行成功,但没有输出。', 'text-green-400'); | |
| commandInput.value = ''; | |
| loadCommandHistory(); | |
| } catch (error) { | |
| console.error('执行命令时出错:', error); | |
| clearOutput(); | |
| appendToOutput('$ ' + command, 'text-blue-400'); | |
| appendToOutput('错误: ' + (error.message || '未知错误'), 'text-red-500'); | |
| if (error.message.includes('Token 刷新失败')) { | |
| showNotification('访问被拒绝。请重新登录。', 'error'); | |
| localStorage.removeItem('token'); | |
| localStorage.removeItem('username'); | |
| localStorage.removeItem('password'); | |
| checkLoginStatus(); | |
| } | |
| } finally { | |
| showLoading(false); | |
| } | |
| } | |
| function clearOutput() { | |
| output.innerHTML = ''; | |
| } | |
| function appendToOutput(text, className = 'text-green-400') { | |
| const lines = text.split('\n'); | |
| lines.forEach((line, index) => { | |
| const p = document.createElement('p'); | |
| p.className = className; | |
| p.textContent = line; | |
| output.appendChild(p); | |
| }); | |
| output.scrollTop = output.scrollHeight; | |
| } | |
| async function loadCommandHistory() { | |
| try { | |
| const response = await fetch('/api/command-history', { | |
| headers: { | |
| 'Authorization': `Bearer ${localStorage.getItem('token')}` | |
| } | |
| }); | |
| const data = await response.json(); | |
| history.innerHTML = ''; | |
| data.reverse().forEach(item => { | |
| const li = document.createElement('li'); | |
| li.innerHTML = ` | |
| <div class="flex justify-between items-center p-2 hover:bg-gray-700 rounded transition-colors duration-200"> | |
| <span class="font-semibold text-blue-400">${filterXSS(item.command)}</span> | |
| <span class="text-sm text-gray-500">${new Date(item.timestamp).toLocaleString()}</span> | |
| </div> | |
| `; | |
| li.className = 'cursor-pointer'; | |
| li.onclick = () => { | |
| commandInput.value = item.command; | |
| commandInput.focus(); | |
| }; | |
| history.appendChild(li); | |
| }); | |
| } catch (error) { | |
| console.error('加载命令历史失败:', error); | |
| showNotification('加载命令历史失败', 'error'); | |
| } | |
| } | |
| function showLoading(isLoading) { | |
| loadingIndicator.style.display = isLoading ? 'block' : 'none'; | |
| executeButton.disabled = isLoading; | |
| executeButton.classList.toggle('opacity-50', isLoading); | |
| } | |
| async function login() { | |
| const username = document.getElementById('username').value; | |
| const password = document.getElementById('password').value; | |
| try { | |
| const response = await fetch('/api/login', { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ username, password }) | |
| }); | |
| const data = await response.json(); | |
| if (response.ok) { | |
| localStorage.setItem('token', data.token); | |
| localStorage.setItem('username', username); | |
| localStorage.setItem('password', password); | |
| document.getElementById('loginForm').style.display = 'none'; | |
| document.getElementById('commandInterface').style.display = 'block'; | |
| loadCommandHistory(); | |
| showNotification('登录成功', 'success'); | |
| } else { | |
| showNotification('登录失败: ' + data.error, 'error'); | |
| } | |
| } catch (error) { | |
| showNotification('登录错误: ' + error.message, 'error'); | |
| } | |
| } | |
| async function refreshToken() { | |
| const username = localStorage.getItem('username'); | |
| const password = localStorage.getItem('password'); | |
| if (!username || !password) { | |
| document.getElementById('loginForm').style.display = 'block'; | |
| document.getElementById('commandInterface').style.display = 'none'; | |
| return; | |
| } | |
| try { | |
| const response = await fetch('/api/login', { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ username, password }) | |
| }); | |
| const data = await response.json(); | |
| if (response.ok) { | |
| localStorage.setItem('token', data.token); | |
| return true; | |
| } else { | |
| throw new Error(data.error); | |
| } | |
| } catch (error) { | |
| console.error('刷新 token 失败:', error); | |
| return false; | |
| } | |
| } | |
| function showNotification(message, type = 'info') { | |
| const notification = document.createElement('div'); | |
| notification.textContent = message; | |
| notification.className = `fixed top-4 right-4 p-4 rounded-lg text-white ${type === 'error' ? 'bg-red-500' : 'bg-green-500'} shadow-lg transition-opacity duration-300`; | |
| document.body.appendChild(notification); | |
| setTimeout(() => { | |
| notification.style.opacity = '0'; | |
| setTimeout(() => notification.remove(), 300); | |
| }, 3000); | |
| } | |
| document.getElementById('loginButton').addEventListener('click', login); | |
| function checkLoginStatus() { | |
| const token = localStorage.getItem('token'); | |
| if (token) { | |
| document.getElementById('loginForm').style.display = 'none'; | |
| document.getElementById('commandInterface').style.display = 'block'; | |
| loadCommandHistory(); | |
| } | |
| } | |
| window.addEventListener('load', checkLoginStatus); | |
| document.getElementById('executeButton').addEventListener('click', executeCommand); | |
| // 添加打字机效果 | |
| function typeWriter(element, text, speed = 50) { | |
| let i = 0; | |
| function type() { | |
| if (i < text.length) { | |
| element.textContent += text.charAt(i); | |
| i++; | |
| setTimeout(type, speed); | |
| } | |
| } | |
| type(); | |
| } | |
| // 在页面加载时添加一些酷炫的效果 | |
| window.addEventListener('load', () => { | |
| const title = document.querySelector('h1'); | |
| title.textContent = ''; | |
| typeWriter(title, 'Web 命令执行器', 100); | |
| }); |