原生JS模拟表单提交要用到 formData
先看截图:
index.html是入口文件,同级的upload.php是PHP上传接口
看代码:
提示:这里直接是multiple上传多个文件的,如果是上传单文件的只需限制下上传文件的数量就行了,这里的upload.php是单文件和多文件统一上传接口,都支持
- index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>单/多文件上传demo</title>
<style>
*{
margin:0;
padding:0;
}
html,body{
width:100%;
height:100%;
}
ul,dl,ol{
list-style: none;
padding:0;
margin:0;
}
.out-box{
width:100%;
height:100%;
overflow: auto;
background:#f5f5f5;
}
.in-box{
width:800px;
height:800px;
background:#f5f81a;
box-sizing: border-box;
padding:30px;
margin:0 auto;
}
.up-btn{
outline: none;
border:none;
background:#782ef3;
color:#fff;
font-size:32px;
padding:16px 32px;
border-radius:64px;
cursor:pointer;
}
.up-btn:active{
background:#6a18f3;
}
.notice{
font-size:32px ;
color:#ccc;
margin-left:15px;
}
.info-box{
padding:30px 0;
font-size:32px;
color:#f6960d;
}
.file-box{
font-size:24px;
font-weight:bold;
color:#30ec0b;
padding:6px;
max-height:200px;
overflow:auto;
}
.fail-box{
font-size:24px;
font-weight:bold;
color:#fb3131;
padding:6px;
max-height:200px;
overflow:auto;
}
</style>
<script>
window.onload = function(){
upBtn.onclick = function(){
upFile.click();
}
upFile.onchange = function(e){
let files = [].slice.call(e.target.files,0);
let successList = [];
let fileHtml = '',failHtml='';
let max = 1024*1024*5; //最大5M,其他限制自行添加,比如限制GIF,JPG,PNG格式等等
for(let i in files){
if(files[i].size >= max){
failHtml += `<li class="fail-item"><span class="failname">${files[i].name}</span></li>`;
}else{
successList.push(files[i]);
fileHtml += `<li class="file-item"><span class="filename">${files[i].name}</span> <span class="size">${getSizeFormat(files[i].size)}</span></li>`
}
}
fileBox.innerHTML = fileHtml;
failBox.innerHTML = failHtml;
upload(successList);
}
/*
传递过来 btyes 的 size 值,转换成 大一点的单位 返回
*/
function getSizeFormat(num){
let str = '';
if(num<1024){
str = num+'btyes';
}else if (num<1024*1024){
str = Math.ceil(num / 1024) + 'KB';
}else if (num<1024*1024*1024){
str = Math.ceil(num / (1024 * 1024)) + 'MB';
}
return str;
}
}
//ajax模拟表单上传文件携带额外参数
function upload(files){
let formData = new FormData();
formData.append('p1',1);
formData.append('p2',2);
formData.append('p3',3);
formData.append('p4',4);
files.map(el=>{
formData.append('files[]',el);
})
let xhr = getXhr();
xhr.open('POST','/upload.php',true);
xhr.withCredentials = false;
xhr.send(formData);
// 处理返回数据
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if(xhr.status == 200){
console.log("xhr.response",xhr.response);
}
}
}
}
//获取 request 对象
function getXhr(){
let xhr=null;
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
} else {
//为了兼容IE6
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
return xhr;
}
</script>
</head>
<body>
<div class="out-box">
<div class="in-box">
<button class="up-btn" id="upBtn">上传文件</button><span class="notice">上传文件最大为5M</span>
<div class="info-box">
<p>上传成功文件</p>
<ul class="file-box" id="fileBox">
</ul>
</div>
<div class="info-box">
<p>上传失败文件</p>
<ul class="fail-box" id="failBox">
</ul>
</div>
</div>
</div>
<input style="display:none;" type="file" name="file" multiple id="upFile">
</body>
</html>
- upload.php
<?php
$p1 = $_REQUEST['p1'];
$p2 = $_REQUEST['p2'];
$p3 = $_REQUEST['p3'];
$p4 = $_REQUEST['p4'];
$files = $_FILES['files'];
//将上传获取到的files数据重组
$newFiles = resetArr($files);
//将上传的文件储存起来
foreach($newFiles as $v){
//这里我没添加判断,如果有需求,自行添加各种判断,判断是目录是否存在,判断文件是否存在决定是否覆盖等等
move_uploaded_file($v['tmp_name'],'./'.$v['name']);
}
//接收到的数据重组
function resetArr($fileList){
foreach($fileList as $key=>$file){
foreach($file as $k=>$v){
$newArr[$k][$key] = $v;
}
}
return $newArr;
}