京东图床

京东图床无压缩,但是有5MB的大小限制,便捷上传工具http://wzapi.com/jdtc

接口地址: https://wzapi.com/api/jdtc

返回格式: JSON

请求方式: POST

请求示例: https://wzapi.com/api/jdtc

请求参数说明:

名称 必填 类型 说明
file 文件 上传的图片文件,字段名为 file。

返回参数说明:

名称 类型 说明

返回示例:

{
  "errno": 0,
  "message": "上传成功",
  "data": {
    "url": "https://img20.360buyimg.com/openfeedback/jfs/t1/258318/30/4667/49469/6770fc21Faed10f9c/ca2af265ef0cf136.jpg",
    "fileName": "万站API.png"
  }
}

请求参数设置:

参数名称 参数值


{
  "errno": 0,
  "message": "上传成功",
  "data": {
    "url": "https://img20.360buyimg.com/openfeedback/jfs/t1/258318/30/4667/49469/6770fc21Faed10f9c/ca2af265ef0cf136.jpg",
    "fileName": "万站API.png"
  }
}

错误码格式说明:

名称 类型 说明

代码示例:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>京东图床 - 万站API</title>
<meta name="description" content="京东图床API,支持JPG、PNG、GIF等图片格式上传,快速稳定,免费使用。">
<meta name="keywords" content="京东图床,图片上传,图床API,免费图床">

<!-- Stylesheets -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/layui@2.8.18/dist/css/layui.css">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<style>
/* Critical CSS - Above the fold styles */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: #f0f2f5;
color: #333;
min-height: 100vh;
position: relative;
overflow-x: hidden;
/* 性能优化 */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
}

body::before {
content: '';
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background:
radial-gradient(circle at 20% 80%, rgba(120, 119, 198, 0.1) 0%, transparent 50%),
radial-gradient(circle at 80% 20%, rgba(255, 119, 198, 0.1) 0%, transparent 50%),
radial-gradient(circle at 40% 40%, rgba(120, 219, 255, 0.1) 0%, transparent 50%);
z-index: -1;
}

.main-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
padding: 20px;
}

.glass-container {
background: rgba(255, 255, 255, 0.25);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.18);
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
width: 100%;
max-width: 500px;
padding: 40px;
position: relative;
overflow: hidden;
/* 性能优化 */
will-change: transform;
transform: translateZ(0);
contain: layout style paint;
}

.glass-container::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
transition: left 0.5s;
}

.glass-container:hover::before {
left: 100%;
}

.header {
text-align: center;
margin-bottom: 30px;
}

.title {
font-size: 28px;
font-weight: 600;
color: #2c3e50;
margin-bottom: 8px;
letter-spacing: -0.5px;
}

.subtitle {
color: #7f8c8d;
font-size: 14px;
font-weight: 400;
}

.upload-zone {
border: 2px dashed rgba(52, 152, 219, 0.3);
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
padding: 40px 20px;
margin: 20px 0;
transition: all 0.3s ease;
cursor: pointer;
position: relative;
text-align: center;
}

.upload-zone:hover {
border-color: rgba(52, 152, 219, 0.6);
background: rgba(255, 255, 255, 0.2);
transform: translateY(-2px);
}

.upload-zone.dragover {
border-color: #3498db;
background: rgba(52, 152, 219, 0.1);
transform: scale(1.02);
}

.upload-icon {
font-size: 48px;
color: #3498db;
margin-bottom: 15px;
opacity: 0.8;
}

.upload-text {
font-size: 16px;
color: #2c3e50;
margin-bottom: 8px;
font-weight: 500;
}

.upload-hint {
color: #7f8c8d;
font-size: 13px;
}

input[type="file"] {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
cursor: pointer;
pointer-events: none;
}


@media (max-width: 768px) {
input[type="file"] {
pointer-events: auto;
z-index: 10;
}

.upload-zone {
touch-action: manipulation;
-webkit-tap-highlight-color: transparent;
position: relative;
}

.upload-zone.file-selected {
pointer-events: none;
opacity: 0.6;
background: rgba(255, 255, 255, 0.05);
}

.upload-zone.file-selected::after {
content: '已选择文件';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: #2ecc71;
font-weight: 600;
font-size: 16px;
z-index: 5;
}

.upload-zone.file-selected .upload-icon,
.upload-zone.file-selected .upload-text,
.upload-zone.file-selected .upload-hint {
opacity: 0.3;
}
}

.file-card {
background: rgba(255, 255, 255, 0.2);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.3);
padding: 20px;
margin: 20px 0;
display: none;
}

.file-info {
display: flex;
align-items: center;
margin-bottom: 15px;
}

.file-icon {
width: 40px;
height: 40px;
background: rgba(52, 152, 219, 0.1);
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 15px;
color: #3498db;
}

.file-details h4 {
color: #2c3e50;
font-size: 16px;
margin-bottom: 4px;
}

.file-details p {
color: #7f8c8d;
font-size: 13px;
}

.upload-btn {
width: 100%;
height: 45px;
background: rgba(52, 152, 219, 0.9);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
color: white;
font-size: 16px;
font-weight: 500;
cursor: pointer;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}

.upload-btn:hover {
background: rgba(52, 152, 219, 1);
transform: translateY(-1px);
box-shadow: 0 4px 15px rgba(52, 152, 219, 0.4);
}

.upload-btn:disabled {
opacity: 0.6;
cursor: not-allowed;
transform: none;
}

.result-area {
margin-top: 20px;
padding: 20px;
background: rgba(255, 255, 255, 0.15);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
display: none;
}

.result-area.success {
background: rgba(46, 204, 113, 0.15);
border-color: rgba(46, 204, 113, 0.3);
}

.result-area.error {
background: rgba(231, 76, 60, 0.15);
border-color: rgba(231, 76, 60, 0.3);
}

.result-content {
text-align: center;
}

.result-icon {
font-size: 32px;
margin-bottom: 15px;
}

.result-icon.success {
color: #2ecc71;
}

.result-icon.error {
color: #e74c3c;
}

.result-title {
font-size: 18px;
font-weight: 600;
margin-bottom: 15px;
color: #2c3e50;
}

.url-container {
background: rgba(255, 255, 255, 0.2);
padding: 15px;
margin: 15px 0;
border: 1px solid rgba(255, 255, 255, 0.3);
}

.url-link {
color: #3498db;
text-decoration: none;
word-break: break-all;
font-family: 'Courier New', monospace;
font-size: 14px;
}

.url-link:hover {
text-decoration: underline;
}

.action-buttons {
margin-top: 20px;
}

.action-btn {
background: rgba(255, 255, 255, 0.2);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.3);
color: #2c3e50;
padding: 8px 16px;
margin: 0 5px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
}

.action-btn:hover {
background: rgba(255, 255, 255, 0.3);
transform: translateY(-1px);
}

.action-btn.primary {
background: rgba(52, 152, 219, 0.8);
color: white;
}

.action-btn.primary:hover {
background: rgba(52, 152, 219, 1);
}

.uploaded-image {
max-width: 100%;
height: auto;
margin: 15px 0;
border: 1px solid rgba(255, 255, 255, 0.3);
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
/* 性能优化 */
will-change: transform;
transform: translateZ(0);
backface-visibility: hidden;
}

.loading {
display: inline-block;
width: 16px;
height: 16px;
border: 2px solid rgba(255, 255, 255, 0.3);
border-top: 2px solid #3498db;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-right: 8px;
}

@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}

@media (max-width: 768px) {
.glass-container {
margin: 10px;
padding: 30px 20px;
/* 移动端性能优化 */
-webkit-overflow-scrolling: touch;
overscroll-behavior: contain;
}

.title {
font-size: 24px;
}

.upload-zone {
padding: 30px 15px;
/* 移动端触摸优化 */
-webkit-tap-highlight-color: transparent;
touch-action: manipulation;
}

.upload-icon {
font-size: 36px;
}

/* 移动端按钮优化 */
.upload-btn, .action-btn {
min-height: 44px; /* iOS推荐的最小触摸目标 */
touch-action: manipulation;
}
}

.fade-in {
animation: fadeIn 0.5s ease-out;
}

@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}

/* 性能优化:减少重绘和重排 */
.upload-zone, .glass-container, .upload-btn {
contain: layout style paint;
}

/* 优化动画性能 */
.glass-container::before {
will-change: left;
}

.upload-zone:hover {
will-change: transform;
}

/* 减少不必要的重绘 */
.uploaded-image, .result-area {
contain: layout style paint;
}
</style>
</head>
<body>
<main class="main-container" role="main">
<article class="glass-container">
<header class="header">
<h1 class="title">
<i class="fas fa-cloud-upload-alt" aria-hidden="true"></i> 云端图床
</h1>
<p class="subtitle">京东图床官方更快 · 快速上传分享</p>
</header>

<form id="uploadForm" role="form" aria-label="图片上传表单">
<div class="upload-zone" id="uploadZone" role="button" tabindex="0"
aria-label="点击或拖拽文件到此处上传图片"
aria-describedby="upload-hint">
<div class="upload-icon" aria-hidden="true">
<i class="fas fa-cloud-upload-alt"></i>
</div>
<div class="upload-text">点击或拖拽文件到此处</div>
<div class="upload-hint" id="upload-hint">支持 JPG、PNG、GIF 等图片格式,最大 5MB</div>
<input type="file" id="fileInput" name="file" accept="image/*" required
aria-label="选择图片文件" />
</div>

<section id="fileCard" class="file-card" aria-label="文件信息" style="display: none;">
<div class="file-info">
<div class="file-icon" aria-hidden="true">
<i class="fas fa-image"></i>
</div>
<div class="file-details">
<h4 id="fileName">文件名</h4>
<p id="fileSize">文件大小</p>
</div>
</div>
</section>

<button type="submit" id="uploadBtn" class="upload-btn"
aria-label="开始上传图片">
<i class="fas fa-upload" aria-hidden="true"></i> 开始上传
</button>
</form>

<section id="resultArea" class="result-area" aria-label="上传结果" style="display: none;">
<div class="result-content" id="resultContent"></div>
</section>
</article>
</main>

<!-- 异步加载非关键JavaScript -->
<script src="https://cdn.jsdelivr.net/npm/layui@2.8.18/dist/layui.js" async></script>
<script>
// 性能优化:使用requestIdleCallback进行非关键任务
function runWhenIdle(callback) {
if (window.requestIdleCallback) {
requestIdleCallback(callback);
} else {
setTimeout(callback, 1);
}
}

// 防抖函数优化性能
function debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
// 延迟加载非关键库
runWhenIdle(() => {
if (typeof layui !== 'undefined') {
layui.use(['layer', 'form'], function(){
var layer = layui.layer;
var form = layui.form;
});
}
});

// DOM元素缓存
const elements = {
uploadForm: document.getElementById('uploadForm'),
fileInput: document.getElementById('fileInput'),
uploadZone: document.getElementById('uploadZone'),
uploadBtn: document.getElementById('uploadBtn'),
fileCard: document.getElementById('fileCard'),
fileName: document.getElementById('fileName'),
fileSize: document.getElementById('fileSize'),
resultArea: document.getElementById('resultArea'),
resultContent: document.getElementById('resultContent')
};

// 错误处理
function handleError(error, context = '') {
console.error(`Error in ${context}:`, error);
showResult(`
<div class="result-icon error">
<i class="fas fa-exclamation-triangle"></i>
</div>
<div class="result-title">操作失败</div>
<p style="color: #e74c3c;">${error.message || '未知错误'}</p>
`, 'error');
}

// 使用防抖优化拖拽事件
const debouncedDragLeave = debounce((e) => {
e.preventDefault();
elements.uploadZone.classList.remove('dragover');
}, 100);

elements.uploadZone.addEventListener('dragover', (e) => {
e.preventDefault();
elements.uploadZone.classList.add('dragover');
});

elements.uploadZone.addEventListener('dragleave', debouncedDragLeave);

elements.uploadZone.addEventListener('drop', (e) => {
e.preventDefault();
elements.uploadZone.classList.remove('dragover');

const files = e.dataTransfer.files;
if (files.length > 0) {
elements.fileInput.files = files;
showFileInfo(files[0]);
}
});

// 检测是否为移动设备
const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);

// 防止重复点击
let isSelectingFile = false;

elements.uploadZone.addEventListener('click', (e) => {
if (isSelectingFile) return;
isSelectingFile = true;
elements.fileInput.click();
// 重置标志,防止重复触发
setTimeout(() => {
isSelectingFile = false;
}, 1000);
});

// 键盘导航支持
elements.uploadZone.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
if (isSelectingFile) return;
isSelectingFile = true;
elements.fileInput.click();
setTimeout(() => {
isSelectingFile = false;
}, 1000);
}
});

// 手机端触摸事件处理
if (isMobile) {
elements.uploadZone.addEventListener('touchstart', (e) => {
e.preventDefault();
}, { passive: false });

elements.uploadZone.addEventListener('touchend', (e) => {
e.preventDefault();
if (isSelectingFile) return;
isSelectingFile = true;
elements.fileInput.click();
setTimeout(() => {
isSelectingFile = false;
}, 1000);
}, { passive: false });
}

elements.fileInput.addEventListener('change', (e) => {
if (e.target.files.length > 0) {
showFileInfo(e.target.files[0]);
}
});

function showFileInfo(file) {
try {
elements.fileName.textContent = file.name;
elements.fileSize.textContent = formatFileSize(file.size);
elements.fileCard.style.display = 'block';

// 手机端特殊处理:不隐藏上传区域,而是添加禁用状态
if (isMobile) {
elements.uploadZone.classList.add('file-selected');
elements.uploadZone.style.pointerEvents = 'none';
} else {
elements.uploadZone.style.display = 'none';
}

elements.resultArea.style.display = 'none';
} catch (error) {
handleError(error, 'showFileInfo');
}
}

function formatFileSize(bytes) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}

function resetUploadArea() {
try {
// 重置手机端状态
if (isMobile) {
elements.uploadZone.classList.remove('file-selected');
elements.uploadZone.style.pointerEvents = 'auto';
} else {
elements.uploadZone.style.display = 'block';
}

elements.fileCard.style.display = 'none';
elements.resultArea.style.display = 'none';
elements.fileInput.value = '';
elements.uploadBtn.disabled = false;
elements.uploadBtn.innerHTML = '<i class="fas fa-upload" aria-hidden="true"></i> 开始上传';
isSelectingFile = false;
} catch (error) {
handleError(error, 'resetUploadArea');
}
}

elements.uploadForm.addEventListener('submit', async (e) => {
e.preventDefault();

const file = elements.fileInput.files[0];
if (!file) {
showResult('请先选择文件!', 'error');
return;
}

if (!file.type.startsWith('image/')) {
showResult('请选择图片文件!', 'error');
return;
}

if (file.size > 10 * 1024 * 1024) {
showResult('文件大小不能超过10MB!', 'error');
return;
}

elements.uploadBtn.disabled = true;
elements.uploadBtn.innerHTML = '<div class="loading"></div>上传中...';

const formData = new FormData();
formData.append('file', file);

try {
// 添加超时控制
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 30000); // 30秒超时

const response = await fetch('https://wzapi.com/api/jdtc', {
method: 'POST',
body: formData,
signal: controller.signal
});

clearTimeout(timeoutId);

if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}

const data = await response.json();

if (data.errno === 0) {
showResult(`
<div class="result-icon success">
<i class="fas fa-check-circle" aria-hidden="true"></i>
</div>
<div class="result-title">上传成功!</div>
<div class="url-container">
<a href="${data.data.url}" target="_blank" class="url-link"
aria-label="查看上传的图片">${data.data.url}</a>
</div>
<p style="color: #7f8c8d; font-size: 14px; margin: 10px 0;">文件名: ${data.data.imgFile}</p>
<img src="${data.data.url}" alt="上传的图片" class="uploaded-image"
loading="lazy" />
<div class="action-buttons">
<button onclick="copyToClipboard('${data.data.url}')" class="action-btn primary"
aria-label="复制图片链接">
<i class="fas fa-copy" aria-hidden="true"></i> 复制链接
</button>
<button onclick="resetUploadArea()" class="action-btn"
aria-label="继续上传其他图片">
<i class="fas fa-upload" aria-hidden="true"></i> 继续上传
</button>
</div>
`, 'success');
} else {
showResult(`
<div class="result-icon error">
<i class="fas fa-exclamation-triangle" aria-hidden="true"></i>
</div>
<div class="result-title">上传失败</div>
<p style="color: #e74c3c;">${data.error}</p>
`, 'error');
}
} catch (error) {
if (error.name === 'AbortError') {
showResult(`
<div class="result-icon error">
<i class="fas fa-clock" aria-hidden="true"></i>
</div>
<div class="result-title">上传超时</div>
<p style="color: #e74c3c;">上传时间过长,请检查网络连接后重试</p>
`, 'error');
} else {
handleError(error, 'upload');
}
} finally {
elements.uploadBtn.disabled = false;
elements.uploadBtn.innerHTML = '<i class="fas fa-upload" aria-hidden="true"></i> 开始上传';
}
});

function showResult(content, type) {
try {
elements.resultContent.innerHTML = content;
elements.resultArea.className = `result-area ${type} fade-in`;
elements.resultArea.style.display = 'block';
} catch (error) {
handleError(error, 'showResult');
}
}

function copyToClipboard(text) {
try {
if (navigator.clipboard && window.isSecureContext) {
navigator.clipboard.writeText(text).then(() => {
showResult(`
<div class="result-icon success">
<i class="fas fa-check" aria-hidden="true"></i>
</div>
<div class="result-title">链接已复制到剪贴板!</div>
`, 'success');
}).catch((error) => {
console.warn('Clipboard API failed:', error);
fallbackCopyTextToClipboard(text);
});
} else {
fallbackCopyTextToClipboard(text);
}
} catch (error) {
handleError(error, 'copyToClipboard');
}
}

function fallbackCopyTextToClipboard(text) {
try {
const textArea = document.createElement('textarea');
textArea.value = text;
textArea.style.position = 'fixed';
textArea.style.left = '-999999px';
textArea.style.top = '-999999px';
textArea.setAttribute('readonly', '');
document.body.appendChild(textArea);
textArea.focus();
textArea.select();

const successful = document.execCommand('copy');
if (successful) {
showResult(`
<div class="result-icon success">
<i class="fas fa-check" aria-hidden="true"></i>
</div>
<div class="result-title">链接已复制到剪贴板!</div>
`, 'success');
} else {
showResult(`
<div class="result-icon error">
<i class="fas fa-exclamation-triangle" aria-hidden="true"></i>
</div>
<div class="result-title">复制失败</div>
<p style="color: #e74c3c;">请手动复制链接</p>
`, 'error');
}
} catch (err) {
handleError(err, 'fallbackCopyTextToClipboard');
} finally {
if (textArea && textArea.parentNode) {
document.body.removeChild(textArea);
}
}
}

window.resetUploadArea = resetUploadArea;
window.copyToClipboard = copyToClipboard;
</script>
</body>
</html>