用html写一个类似于postman可以发送请求
效果图

代码
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>API请求工具 - Postman风格</title><link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet"><script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"><style>* {margin: 0;padding: 0;box-sizing: border-box;font-family: 'Roboto', sans-serif;}:root {--primary: #ff6b35;--secondary: #2d5d7b;--dark: #1e2a38;--light: #f5f7fa;--success: #4caf50;--warning: #ff9800;--danger: #f44336;--gray: #78909c;}body {background-color: #f0f2f5;color: #333;line-height: 1.6;}.container {max-width: 1200px;margin: 0 auto;padding: 20px;}header {background: linear-gradient(135deg, var(--dark), var(--secondary));color: white;padding: 15px 0;margin-bottom: 30px;border-radius: 8px;box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);}.header-content {display: flex;justify-content: space-between;align-items: center;padding: 0 20px;}.logo {display: flex;align-items: center;gap: 10px;}.logo i {font-size: 28px;color: var(--primary);}.logo h1 {font-size: 24px;font-weight: 700;}.request-controls {display: flex;gap: 20px;background-color: white;padding: 20px;border-radius: 8px;box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);margin-bottom: 25px;}.method-select {width: 120px;padding: 10px;border: 1px solid #ddd;border-radius: 4px;background-color: white;font-weight: 500;color: var(--secondary);}.url-input {flex: 1;padding: 10px 15px;border: 1px solid #ddd;border-radius: 4px;font-size: 16px;}.send-btn {padding: 10px 25px;background: linear-gradient(135deg, var(--primary), #ff5722);color: white;border: none;border-radius: 4px;cursor: pointer;font-weight: 600;transition: all 0.3s ease;box-shadow: 0 2px 4px rgba(255, 107, 53, 0.3);}.send-btn:hover {background: linear-gradient(135deg, #ff5722, var(--primary));transform: translateY(-2px);box-shadow: 0 4px 8px rgba(255, 107, 53, 0.4);}.send-btn:active {transform: translateY(0);}.section {background-color: white;border-radius: 8px;box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);margin-bottom: 25px;overflow: hidden;}.section-header {background-color: var(--light);padding: 12px 20px;font-weight: 600;color: var(--secondary);border-bottom: 1px solid #eee;display: flex;align-items: center;gap: 8px;}.section-content {padding: 20px;}.form-group {margin-bottom: 20px;}.form-group label {display: block;margin-bottom: 8px;font-weight: 500;color: var(--dark);}textarea {width: 100%;min-height: 150px;padding: 15px;border: 1px solid #ddd;border-radius: 4px;font-size: 14px;font-family: monospace;resize: vertical;}.response-info {display: flex;gap: 20px;margin-bottom: 20px;}.status-badge {padding: 6px 12px;background-color: var(--success);color: white;border-radius: 4px;font-weight: 600;font-size: 14px;}.size-info {color: var(--gray);font-size: 14px;display: flex;align-items: center;gap: 5px;}.response-view {position: relative;border: 1px solid #eee;border-radius: 4px;overflow: hidden;}.response-content {padding: 15px;font-family: monospace;font-size: 14px;background-color: #fafafa;white-space: pre-wrap;word-break: break-all;min-height: 200px;max-height: 500px;overflow-y: auto;}.copy-btn {position: absolute;top: 10px;right: 10px;padding: 6px 10px;background-color: white;border: 1px solid #ddd;border-radius: 4px;cursor: pointer;color: var(--gray);transition: all 0.2s;}.copy-btn:hover {background-color: var(--light);color: var(--secondary);}.input-row {display: flex;gap: 15px;margin-bottom: 15px;}.input-row .form-group {flex: 1;margin-bottom: 0;}.input-row input {width: 100%;padding: 10px;border: 1px solid #ddd;border-radius: 4px;}.instructions {background-color: #fff8e1;padding: 15px;border-radius: 6px;font-size: 14px;color: #333;margin-top: 25px;border-left: 4px solid var(--warning);}.instructions h3 {margin-bottom: 10px;color: var(--dark);}.instructions ul {margin-left: 20px;}.instructions li {margin-bottom: 8px;}@media (max-width: 768px) {.header-content {flex-direction: column;gap: 15px;text-align: center;}.request-controls {flex-direction: column;}.input-row {flex-direction: column;gap: 10px;}}.footer {text-align: center;padding: 20px;color: var(--gray);font-size: 14px;margin-top: 30px;}</style>
</head>
<body><header><div class="header-content"><div class="logo"><i class="fas fa-bolt"></i><h1>API请求工具</h1></div><p>模拟Postman的HTTP请求测试工具</p></div></header><div class="container"><div class="request-controls"><select class="method-select" id="method-select"><option value="GET">GET</option><option value="POST">POST</option><option value="PUT">PUT</option><option value="DELETE">DELETE</option><option value="PATCH">PATCH</option></select><input type="url" class="url-input" id="url-input" placeholder="输入请求URL..." value=""><button class="send-btn" id="send-btn"><i class="fas fa-paper-plane"></i> 发送请求</button></div><div class="section"><div class="section-header"><i class="fas fa-edit"></i><span>请求头</span></div><div class="section-content"><div class="input-row"><div class="form-group"><label>Header Key</label><input type="text" id="header-key" placeholder="例如: Content-Type"></div><div class="form-group"><label>Header Value</label><input type="text" id="header-value" placeholder="例如: application/json"></div></div></div></div><div class="section"><div class="section-header"><i class="fas fa-code"></i><span>请求体 (JSON格式)</span></div><div class="section-content"><div class="form-group"><textarea id="request-body" placeholder='{"key1": "value1","key2": "value2"
}'></textarea></div></div></div><div class="section"><div class="section-header"><i class="fas fa-reply"></i><span>响应内容</span></div><div class="section-content"><div class="response-info"><div class="status-badge" id="status-code">等待请求...</div><div class="size-info" id="response-size"><i class="fas fa-weight-hanging"></i> <span>0 Bytes</span></div></div><div class="response-view"><div class="response-content" id="response-content"></div><button class="copy-btn" id="copy-btn"><i class="fas fa-copy"></i> 复制</button></div></div></div><div class="instructions"><h3><i class="fas fa-info-circle"></i> 使用说明</h3><ul><li>选择请求方法(默认为GET),输入URL地址</li><li>可以添加自定义请求头(可选)</li><li>对于POST/PUT请求,可以在请求体区域输入JSON格式数据</li><li>点击"发送请求"按钮提交API请求</li><li>响应区域将显示状态码、响应大小和返回内容</li><li>使用"复制"按钮可以快速复制响应内容</li></ul></div></div><div class="footer"><p>© 2023 API请求工具 | 模拟Postman风格接口测试工具</p></div><script>document.addEventListener('DOMContentLoaded', function() {const sendBtn = document.getElementById('send-btn');const copyBtn = document.getElementById('copy-btn');const urlInput = document.getElementById('url-input');const methodSelect = document.getElementById('method-select');const requestBody = document.getElementById('request-body');const responseContent = document.getElementById('response-content');const statusCode = document.getElementById('status-code');const responseSize = document.querySelector('#response-size span');const headerKey = document.getElementById('header-key');const headerValue = document.getElementById('header-value');updateBodyPlaceholder();methodSelect.addEventListener('change', updateBodyPlaceholder);function updateBodyPlaceholder() {if(methodSelect.value === 'GET') {requestBody.placeholder = "GET请求不需要请求体";requestBody.disabled = true;} else {requestBody.placeholder = '{\n "key1": "value1",\n "key2": "value2"\n}';requestBody.disabled = false;}}sendBtn.addEventListener('click', async function() {const method = methodSelect.value;const url = urlInput.value;const headers = {};if(headerKey.value && headerValue.value) {headers[headerKey.value] = headerValue.value;}let data = null;if(method !== 'GET' && requestBody.value.trim() !== '') {try {data = JSON.parse(requestBody.value);} catch (e) {displayErrorResponse("请求体JSON格式错误: " + e.message);return;}}responseContent.textContent = "发送请求中...";statusCode.textContent = "请求中...";statusCode.style.backgroundColor = '#ff9800';sendBtn.disabled = true;sendBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> 发送中...';try {const response = await axios({method: method,url: url,data: data,headers: headers});updateResponseUI(response);} catch (error) {if (error.response) {updateResponseUI(error.response);} else {displayErrorResponse("请求失败: " + error.message);}} finally {sendBtn.disabled = false;sendBtn.innerHTML = '<i class="fas fa-paper-plane"></i> 发送请求';}});function updateResponseUI(response) {const status = response.status;statusCode.textContent = `${status} ${response.statusText}`;if (status >= 200 && status < 300) {statusCode.style.backgroundColor = '#4caf50'; } else if (status >= 300 && status < 400) {statusCode.style.backgroundColor = '#ff9800'; } else if (status >= 400 && status < 500) {statusCode.style.backgroundColor = '#f44336'; } else if (status >= 500) {statusCode.style.backgroundColor = '#9c27b0'; }let size = 0;if (response.data) {size = JSON.stringify(response.data).length;}let readableSize = size + " Bytes";if (size > 1024) {readableSize = (size / 1024).toFixed(2) + " KB";}responseSize.textContent = readableSize;let formattedResponse;if (typeof response.data === 'object') {formattedResponse = JSON.stringify(response.data, null, 2);} else if (typeof response.data === 'string') {try {formattedResponse = JSON.stringify(JSON.parse(response.data), null, 2);} catch (e) {formattedResponse = response.data;}} else {formattedResponse = response.data;}responseContent.textContent = formattedResponse;}function displayErrorResponse(message) {statusCode.textContent = "错误";statusCode.style.backgroundColor = '#f44336';responseContent.textContent = message;}copyBtn.addEventListener('click', function() {const textToCopy = responseContent.textContent;navigator.clipboard.writeText(textToCopy).then(() => {const originalText = copyBtn.innerHTML;copyBtn.innerHTML = '<i class="fas fa-check"></i> 已复制';setTimeout(() => {copyBtn.innerHTML = originalText;}, 2000);});});});</script>
</body>
</html>