通过ajax异步上传文件不仅可以通过base64还可以上传二进制数据流文件,适合大文件。base64转二进制数据流…
通过ajax异步上传文件不仅可以通过base64还可以上传二进制数据流文件,base64不适合大文件,Blob二进制数据流适合大文件。
原理:通过FileReader获得文件信息,然后在页面上展示选择的文件,通过canvas画图压缩图片,获得base64数据转成Blob二进制数据流,实例化FormData 创建form表单,然后进行ajax异步上传。
demo.html 源码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>HTML文件上传(四) AJAX异步上传文件base64转Blob二进制数据流上传</title>
<script src="http://apps.bdimg.com/libs/jquery/1.8.3/jquery.min.js"></script>
</head>
<body>
<input type="file" id="imagesfile" hidefocus style="display:none">
<img src="./photo_icon.png" width="100" id="imgtmp" onclick="imagesfile.click()" />
<button id="sub_btn" >上传</button>
</body>
</html>
<script>
window.onload = function(){
var imagesfile = document.getElementById("imagesfile");
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
var imgDom = document.getElementById("imgtmp");
imgDom.src = base64;
/*imgDom.onload = function () {
imgDom.onload=null;
//压缩
var canvas = document.createElement('canvas'); // 获取canvas对象
var context = canvas.getContext('2d'); // 获取canvas的上下文
canvas.width = 100;
canvas.height = 100;
context.clearRect(0, 0, canvas.width, canvas.height); // 首先先清空canvas里面的内容,以防内容叠加
context.drawImage(imgDom, 0, 0, canvas.width, canvas.height); // 画图
var base64min = canvas.toDataURL('image/jpeg', 0.92); // 格式和质量
imgDom.src = base64min;
//直接上传图片
//base64_uploading(base64min);
}*/
}
}
}
$('#sub_btn').on('click',function(){
var base64Data = $('#imgtmp').attr('src');
base64_uploading(base64Data);
})
//AJAX上传base64
function base64_uploading(base64Data){
var param1 = '其他参数'; // 可以同时传其他参数
var uploadimg = dataURLtoBlob(base64Data); // base64转二进制数据流
var formData = new FormData(); // 实例化创建form表单
formData.append("uploadimg", uploadimg); // 增加参数
formData.append("param1", param1); // 增加参数
// 执行ajax提交
$.ajax({
url:'upload.php',
dataType:'json',
type:'POST',
async: false,
data: formData,
processData : false, // 使数据不做处理
contentType : false, // 不要设置Content-Type请求头
success: function(data){
console.log(data);
if(data.code == 10000){
alert('上传成功');
}else{
alert('上传失败:'+data.msg);
}
},
error:function(response){
console.log('网络异常:'+response);
}
});
}
//**dataURL to blob**
function dataURLtoBlob(dataurl) {
var arr = dataurl.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 });
}
</script>
后端代码以php为例,upload.php 源码:
<?php
header("Content-type: text/html; charset=utf-8");
error_reporting(E_ALL ^ E_NOTICE);
/**
* 图片上传fun
*/
function fileuploads(){
// 基础配置
$quality = 100; //缩略图质量
$path = './uploads/'; // 图片上传路径
$path_thum = './uploads/thum/'; // 缩略图路径
$fileMaxSize = 10*1024*1024; // 图片最大控制10Mb
// 初始结果集
$result = array('code'=>40000,'msg'=>'参数错误','data'=>array());
// 传参验证
if(!isset($_POST)){
$result['code'] = 40001;
return $result;
}
if(!isset($_FILES)){
$result['code'] = 40002;
return $result;
}
// 上传文件信息验证
if(!$_FILES["uploadimg"]["name"]){
$result['code'] = 30000;
$result['msg'] = '上传文件信息错误';
return $result;
}
$fileSize = $_FILES["uploadimg"]["size"];
$fileType = $_FILES["uploadimg"]["type"];
// 上传文件大小验证
if($fileSize > $fileMaxSize){
$result['code'] = 30001;
$result['msg'] = '上传文件不能超过10Mb';
return $result;
}
$fileTypeVals = array(
'wbmp'=>'image/vnd.wap.wbmp',
//'bmp'=>'application/x-MS-bmp',
'bmp'=>'image/bmp',
'png'=>'image/png',
'gif'=>'image/gif',
'jpg'=>'image/jpeg',
'jpeg'=>'image/pjpeg'
);
// 上传文件类型验证
$fileTypes = array_values($fileTypeVals);
if(!in_array($fileType, $fileTypes)){
$result['code'] = 30002;
$result['msg'] = '上传文件类型不是图片类型';
return $result;
}
// 上传文件出错了
if($_FILES["uploadimg"]["error"] > 0){
$result['code'] = 30003;
$result['msg'] = '文件上传出错了';
return $result;
}
// 上传文件路径验证生成
if(!file_exists($path)){
mkdir($path,0777);
}
if(!file_exists($path)){
if(!mkdir($path)){
$result['code'] = 50000;
$result['msg'] = '文件路径创建失败';
return $result;
}
}
if(!file_exists($path_thum)){
if(!mkdir($path_thum)){
$result['code'] = 50001;
$result['msg'] = '文件缩略图路径创建失败';
return $result;
}
}
// 获取文件后缀,base64转Blob不能通过此方法获得后缀
//$suf = strtolower(pathinfo($_FILES["uploadimg"]["name"], PATHINFO_EXTENSION)); // 文件后缀
// base64转Blob通过以下获得图片后缀
$suf = 'jpg';
foreach($fileTypeVals as $k=>$v){
if($v == $fileType){
$suf = $k;
break;
}
}
// 文件完整路径拼接
$newname = date('YmdHis').'_'.rand(100,999);
$upfile = $path.$newname.'.'.$suf;
$upfile_thum = $path_thum.$newname.'.'.$suf;//缩略图
// 将上传的文件移动到新位置
if(!move_uploaded_file($_FILES["uploadimg"]["tmp_name"],$upfile)){
$result['code'] = 30004;
$result['msg'] = '文件上传出错了';
return $result;
}
// 赋值文件路径
$result['data']['filepath'] = $upfile;
/** 生成缩略图 ->**/
$imagedata = getimagesize($upfile); // 获取图片信息
$olgWidth = $imagedata[0]; // 图片宽
$oldHeight = $imagedata[1]; // 图片高
$newWidth = 100; // 缩略图宽
$newHeight = intval($newWidth)/intval($olgWidth)*intval($oldHeight); // 高等比缩放
// 小于100像素直接按照原图
if($olgWidth < 100){
$newWidth = $olgWidth;
$newHeight = $oldHeight;
}
// 根据图片类型分流
if($suf == 'jpg' || $suf == 'jpe' || $suf == 'jpeg' || $suf == 'jpz'){
$image = imagecreatefromjpeg($upfile);
}else if($suf == 'png'){
$image = imagecreatefrompng($upfile);
if(str_replace('.', '', PHP_VERSION)>= 512){ //针对php版本大于5.12参数变化后的处理情况
$quality = 90;
}
}else if($suf == 'gif'){
$image = imagecreatefromgif($upfile);
}else if($suf == 'bmp'||$suf == 'wbmp'){
$image = imagecreatefromwbmp($upfile);
}
// 是否取得图形
if(!$image){
$result['code'] = 30005;
$result['msg'] = '缩略图生成出错了';
return $result;
}
// 新建一个w*y黑色图像
$thumb = imagecreatetruecolor ($newWidth, $newHeight);
//图像中的一块矩形区域拷贝到另一个图像中
if(function_exists('imagecopyresampled')){
imagecopyresampled($thumb, $image, 0, 0, 0, 0, $newWidth, $newHeight, $olgWidth, $oldHeight);
}else{
imagecopyresized($thumb, $image, 0, 0, 0, 0, $newWidth, $newHeight, $olgWidth, $oldHeight);
}
//将图形输出到目标目录
imagejpeg($thumb, $upfile_thum, $quality);
//释放与 image 关联的内存
imagedestroy($thumb);
imagedestroy($image);
/**<-**/
$result['code'] = 10000;
$result['msg'] = '图片上传成功';
$result['data']['filepath_thum'] = $upfile_thum;
return $result;
}
// 调用
$result = fileuploads();
echo json_encode($result);return;
?>