自己踩过坑不想别人也踩坑了 亚马逊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 10pxrgba(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>
constdropZone=document.getElementById("dropZone" ) ; constfileInput=document.getElementById("fileInput" ) ; constprogressContainer=document.getElementById("progressContainer" ) ; constprogressBar=document.getElementById("progressBar" ) ; conststatus=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 { constresponse= await fetch(`BASEURL?file_name=${file.name }
`
) ; const data = awaitresponse.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) { constpercentComplete= (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>