js异步文件上传base64数据转文件base64文件上传字符过长解决办法
用js异步上传文件的时候一般情况会用base64数据方式上传,但是有时会导致上传的参数字节过大提交失败!以下方案是把base64数据传文件模拟form表单提交,实现页面无刷新的异步文件上传。
其实就一个方法把base64数据串转换成文件二进制对象,如下代码:
/**
* 将文件Base64数据转成blob
*/
function base64File(base64Data) {
var arr = base64Data.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], { type: mime });
}
通过实例化form表单进行追加需要上传的参数
var uploadimg = base64File(base64Data); // 通过获得的图片base64数据转成二进制数据流
var formData = new FormData(); // 实例化创建form表单
formData.append("id", '1000'); // 传id值
formData.append("title", '越加网'); // 传title值
formData.append("uploadimg", uploadimg); // 增加参数传uploadimg
//通过ajax 传formData ……
应用示例:
demo.html源码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>js异步文件上传base64数据转文件base64文件上传字符过长解决办法 - 越加网</title>
<meta name="keywords" content="js异步上传,base64数据转文件,base64文件上传">
<meta name="description" content="js异步文件上传base64数据转文件base64文件上传字符过长解决办法">
</head>
<body>
<div class="box">
<input type="text" id="param_id" placeholder="编号" /><br><br>
<input type="text" id="param_name" placeholder="名称" /><br><br>
<input type="file" id="param_file" /><br><br>
<input type="hidden" id="param_hidden" />
<button onclick="sub_fun();">提交</button>
</div>
</body>
<script src="//apps.bdimg.com/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript">
/**
* 选择文件获取文件base64编码
*/
window.onload = function(){
var imagesfile = document.getElementById("param_file");
imagesfile.onchange = function () {
var file = imagesfile.files[0];
//判断文件大小不能超过10M ,免去服务器的压力。
if (file.size > 10 * 1024 * 1024) {
alert("上传文件必须 < 10Mb!");
return false;
}
// 获取文件
var reader = new FileReader(); // 实例化
reader.readAsDataURL(file); // 加载
reader.onload = function () { // 异步加载完成
console.log(reader);
var base64 = reader.result; // 获取 base64 DataURL
document.getElementById("param_hidden").value = base64;
}
}
}
/**
* 将文件Base64数据转成文件blob二进制
*/
function base64File(base64Data) {
var arr = base64Data.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], { type: mime });
}
/**
* 数据提交方法
*/
function sub_fun(){
var requestUrl = 'test.php';
var id = document.getElementById('param_id').value;
var name = document.getElementById('param_name').value;
var base64 = document.getElementById("param_hidden").value;
if(!id || !name || !base64){
alert('参数不能为空');return;
}
var uploadimg = base64File(base64);
var formData = new FormData(); // 实例化创建form表单
formData.append("id", id);
formData.append("name", name);
formData.append("uploadimg", uploadimg); // 增加参数
// ajax
$.ajax({
url:requestUrl,
dataType:'json',
type:'POST',
async: false,
data: formData,
processData : false, // 使数据不做处理
contentType : false, // 不要设置Content-Type请求头
success: function(data){
console.log(data);
},
error:function(response){
console.log('网络异常:'+response);
}
});
}
</script>
</html>
服务端接收以PHP为例如下:
<?php
$result = array('code'=>'40000','data'=>array());
$id = isset($_REQUEST['id']) ? $_REQUEST['id'] : '';
$name = isset($_REQUEST['name']) ? $_REQUEST['name'] : '';
$result['data']['id'] = $id;
$result['data']['name'] = $name;
if(!isset($_FILES)){
echo json_encode($result);exit;
}
$file = $_FILES['uploadimg']['tmp_name'];
$path = './upload/';
if(!file_exists($path)){
mkdir($path,0777);
}
$newname = time().rand(100,999);
// base64转blob时pathinfo($_FILES["multipartFile"]["name"], PATHINFO_EXTENSION);方式获取不到文件扩展名
$upfile = $path.$newname.'.jpg'; // 默认给个后缀
if(move_uploaded_file($file,$upfile)){
$suf = getFileType($upfile); // 上传成功后获取文件真实扩展名
$updatefile = $path.$newname.'.'.$suf;
$re = rename($upfile, $updatefile); // 修改文件
if($re){
//@unlink($upfile); // 删除老的文件
$upfile = $updatefile; // 重置新的文件路径
}
$result['code'] = 10000;
$result['data']['filepath'] = substr($upfile, 1);
}
echo json_encode($result);exit;
/**
* 判断文件类型
*/
function getFileType($file){
$filehead = fopen($file,'r');
$bin = fread($filehead, 2); //读取文件2字节
fclose($filehead);
$data = unpack('C2chars', $bin);
$type_code = intval($data['chars1'].$data['chars2']);
switch ($type_code) {
case 7790:
$fileType = 'exe';
break;
case 7784:
$fileType = 'midi';
break;
case 8075:
$fileType = 'zip';
break;
case 8297:
$fileType = 'rar';
break;
case 255216:
$fileType = 'jpg';
break;
case 7173:
$fileType = 'gif';
break;
case 6677:
$fileType = 'bmp';
break;
case 13780:
$fileType = 'png';
break;
default:
$fileType = '';
break;
}
return $fileType;
}