blob和base64实现文件上传

来源:程序思维浏览:1640次
有时候,我们不想通过上传本地图片的方式上传图片,而是通过相机拍照,将这个拍照后的图片直接上传到服务器上,不需要保存到本地。

比如,用video模拟一个摄像头,通过webrtc调用摄像头的方式拍一张照,然后通过canvas通过getContext('2d')获取的绘图对象CanvasRenderingContext2D的drawImage(video, x, y, width, heigth)方法将video图像通过canvas直接画到html页面上,用来呈现拍照后的结果。
通常的做法是用

<input type="file"/>

的方式上传图片的。但这种方式是要求图片具体存在的,本地或者url路径上的。
现在我们来通过canvas的toDataURL或者toBlob方法、File对象、FormData对象来通过ajax上传图片。

<video id="video"></video>
<canvas id="canvas"></canvas>

<script type="text/javascript">
    // 调用摄像头的代码省略...
   
    let video = document.querySelector('#video')
    let canvas = document.querySelector('#canvas')
   
    let context = canvas.getContext('2d')
    context.drawImage(video, 0, 0, 300, 150)    // 将video标签的图片画到canvas上
   
    // 正片开始
    // 通过canvas调用toBlob方法获取blob对象,传入一个回调函数,这个回调函数的参数就是blob对象
    let s = canvas.toBlob(function (blob) {
        /*
         * 注意第一个File的构造方法第一个参数必须要用[]包起来,表明这是一个数组
         * 第二个参数是这个文件名
         * 第三个参数是选项,其中通过type指定这个文件的mime值
         */
        let file2 = new File([blob], 'a.jpg', {type: 'image/jpg'})
     
        // ajax上传文件不能像上传普通对象那样,得用上FormData
        let formData = new FormData()
        formData.append('file', file2)

        $.ajax({
            url: '/a',    // 后台接口
            type: 'POST',
            processData: false,    // processData和contentType必须指定为false
            contentType: false,
            cache: false,
            data: formData,
            success(res) {
                console.log("上传完成!")
            }
        })
    });
</script>

第二种方式,通过base64转码,这里只看js代码

这是canvas调用toDataURL方法将图片base64编码



var Img = new Image(),
        dataURL='';
    Img.src=url;
    Img.onload=function(){ //要先确保图片完整获取到,这是个异步事件
        var canvas = document.createElement("canvas"), //创建canvas元素
            width=Img.width, //确保canvas的尺寸和图片一样
            height=Img.height;
        canvas.width=width;
        canvas.height=height;
        canvas.getContext("2d").drawImage(Img,0,0,width,height); //将图片绘制到canvas中
       let base64 = canvas.toDataURL();    // 同样通过canvas的toDataURL方法将canvas图片Base64编码

let bstr = atob(base64.split(',')[1]);    // atob是将base64编码解码,去掉data:image/png;base64,部分
let n = bstr.length;
let u8arr = new Uint8Array(n);

while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
}

// 写法同上
let file2 = new File([u8arr], 'a.jpg', {type: 'image/jpg'})

let formData = new FormData()
formData.append('file', file2)
console.log(formData)

$.ajax({
    url: '/a',
    type: 'POST',
    processData: false,
    contentType: false,
    cache: false,
    data: formData,
    success(res) {
        console.log("上传完成!")
    }
})
};

php上传文件代码:

<?php
/*
接收方法:$_POST[""],$_GET[""],$_REQUEST[""]

$_FILES:把整个文件读入一个数组中
*/
//print_r($_FILES);

/*echo "上传文件名称是:".$_FILES["myfile"]["name"]."<br>";
echo "上传文件类型是:".$_FILES["myfile"]["type"]."<br>";
echo "上传临时文件是:".$_FILES["myfile"]["tmp_name"]."<br>";*/

$copyto="uploadfiles/".time().$_FILES["myfile"]["name"];
$filesize=$_FILES["myfile"]["size"]/1024;

if ($_FILES["myfile"]["error"]>0){
 
  switch($_FILES["myfile"]["error"]){
   case 1:
    echo "<script>alert ('上传文件超过了php.ini中upload_max_filesize这个选项设置的值');history.go(-1)</script>";
    break;
   case 2:
    echo "<script>alert ('上传的文件大小超过了HTML表单中MAX_FILE_SIZE选项指定的值');history.go(-1)</script>";
    break;
   case 3:
    echo "<script>alert ('文件只有被部分上传');history.go(-1)</script>";
    break;
   case 4:
    echo "<script>alert ('没有文件上传');history.go(-1)</script>";
    break;
  }
  exit;
}else{
  if(is_uploaded_file($_FILES["myfile"]["tmp_name"])){
   if($filesize<1024){
    if(move_uploaded_file($_FILES["myfile"]["tmp_name"],$copyto)){
     echo "上传文件成功;上传文件大小为".$_FILES["myfile"]["size"]/1024 ."kb";
    }else{
     echo "上传文件失败";
    }
   }else{
    echo "文件大小超过了限制";
   }
  }
}
?>
精品好课
jQuery视频教程从入门到精通
jquery视频教程从入门到精通,课程主要包含:jquery选择器、jquery事件、jquery文档操作、动画、Ajax、jquery插件的制作、jquery下拉无限加载插件的制作等等......
VUE2+VUE3视频教程从入门到精通(全网最全的Vue课程)
VUE是目前最火的前端框架之一,就业薪资很高,本课程教您如何快速学会VUE+ES6并应用到实战,教你如何解决内存泄漏,常用UI库的使用,自己封装组件,正式上线白屏问题,性能优化等。对正在工作当中或打算学习VUE高薪就...
Vue2+Vue3+ES6+TS+Uni-app开发微信小程序从入门到实战视频教程
2021年最新Vue2+Vue3+ES6+TypeScript和uni-app开发微信小程序从入门到实战视频教程,本课程教你如何快速学会VUE和uni-app并应用到实战,教你如何解决内存泄漏,常用UI库的使用,自己...
HTML5基础入门视频教程易学必会
HTML5基础入门视频教程,教学思路清晰,简单易学必会。适合人群:创业者,只要会打字,对互联网编程感兴趣都可以学。课程概述:该课程主要讲解HTML(学习HTML5的必备基础语言)、CSS3、Javascript(学习...
React实战视频教程仿京东移动端电商
React是前端最火的框架之一,就业薪资很高,本课程教您如何快速学会React并应用到实战,对正在工作当中或打算学习React高薪就业的你来说,那么这门课程便是你手中的葵花宝典。
最新完整React视频教程从入门到精通纯干货纯实战
React是目前最火的前端框架,就业薪资很高,本课程教您如何快速学会React并应用到实战,教你如何解决内存泄漏,常用UI库的使用,自己封装组件,正式上线白屏问题,性能优化等。对正在工作当中或打算学习React高薪就...
HTML5视频播放器video开发教程
适用人群1、有html基础2、有css基础3、有javascript基础课程概述手把手教你如何开发属于自己的HTML5视频播放器,利用mp4转成m3u8格式的视频,并在移动端和PC端进行播放支持m3u8直播格式,兼容...
最新完整React+VUE视频教程从入门到精,企业级实战项目
React和VUE是目前最火的前端框架,就业薪资很高,本课程教您如何快速学会React和VUE并应用到实战,教你如何解决内存泄漏,常用库的使用,自己封装组件,正式上线白屏问题,性能优化等。对正在工作当中或打算学习Re...
收藏
扫一扫关注我们