自己踩过坑不想别人也踩坑了 亚马逊S3存储桶直传前端demo复制即可使用
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>S3 直传示例</title>
<style>
.container {
max-width: 600px;
margin: 50px auto;
padding: 20px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
border-radius: 8px;
}
.upload-area {
border: 2px dashed #ccc;
padding: 20px;
text-align: center;
margin: 20px 0;
border-radius: 4px;
}
.upload-area.dragover {
background-color: #e1f5fe;
border-color: #2196f3;
}
.progress {
margin-top: 20px;
display: none;
}
.progress-bar {
height: 20px;
background-color: #4caf50;
width: 0%;
transition: width 0.3s;
}
.status {
margin-top: 10px;
color: #666;
}
</style>
</head>
<body>
<div class="container">
<h1>S3 直传示例</h1>
<div class="upload-area" id="dropZone">
<p>拖拽文件到这里或点击选择文件</p>
<input type="file" id="fileInput" style="display: none" />
<button onclick="document.getElementById('fileInput').click()">选择文件</button>
</div>
<div class="progress" id="progressContainer">
<div class="progress-bar" id="progressBar"></div>
<div class="status" id="status"></div>
</div>
</div>
<script>
const dropZone = document.getElementById("dropZone");
const fileInput = document.getElementById("fileInput");
const progressContainer = document.getElementById("progressContainer");
const progressBar = document.getElementById("progressBar");
const status = document.getElementById("status");
["dragenter", "dragover", "dragleave", "drop"].forEach((eventName) => {
dropZone.addEventListener(eventName, preventDefaults, false);
});
function preventDefaults(e) {
e.preventDefault();
e.stopPropagation();
}
["dragenter", "dragover"].forEach((eventName) => {
dropZone.addEventListener(eventName, highlight, false);
});
["dragleave", "drop"].forEach((eventName) => {
dropZone.addEventListener(eventName, unhighlight, false);
});
function highlight(e) {
dropZone.classList.add("dragover");
}
function unhighlight(e) {
dropZone.classList.remove("dragover");
}
dropZone.addEventListener("drop", handleDrop, false);
fileInput.addEventListener("change", handleFileSelect, false);
function handleDrop(e) {
const dt = e.dataTransfer;
const files = dt.files;
handleFiles(files);
}
function handleFileSelect(e) {
const files = e.target.files;
handleFiles(files);
}
async function handleFiles(files) {
const file = files[0];
if (!file) return;
try {
const response = await fetch(`BASEURL?file_name=${file.name}`);
const data = await response.json();
if (data.code === 20000) {
progressContainer.style.display = "block";
progressBar.style.width = "0%";
status.textContent = "开始上传...";
const xhr = new XMLHttpRequest();
xhr.upload.onprogress = (e) => {
if (e.lengthComputable) {
const percentComplete = (e.loaded / e.total) * 100;
progressBar.style.width = percentComplete + "%";
status.textContent = `上传进度: ${Math.round(percentComplete)}%`;
}
};
xhr.onload = () => {
if (xhr.status === 200) {
status.textContent = "上传成功!";
status.style.color = "#4CAF50";
} else {
status.textContent = "上传失败,请重试";
status.style.color = "#f44336";
}
};
xhr.onerror = () => {
status.textContent = "上传出错,请重试";
status.style.color = "#f44336";
};
xhr.open(data.data.method, data.data.url);
xhr.send(file);
} else {
throw new Error(data.msg || "获取上传配置失败");
}
} catch (error) {
console.error("上传出错:", error);
status.textContent = "上传出错: " + error.message;
status.style.color = "#f44336";
}
}
</script>
</body>
</html>