文件上传的几种方法——xhr篇

在以往的项目,用过三种方式的文件上传,分别是xhr、webuploader、plupload,好记性不如烂笔头,在开始整理笔记的时候,文件上传的优先级就排得敲级高,毕竟特别常用嘛~表达能力有限,只能无限开门放代码。。。


xhr

这个方法的兼容性不太好。

XMLHttpRequest一开始只是微软浏览器提供的一个接口,后来各大浏览器纷纷效仿也提供了这个接口,再后来W3C对它进行了标准化,提出了XMLHttpRequest标准。XMLHttpRequest标准又分为Level 1和Level 2。
XMLHttpRequest Level 1主要存在以下缺点:
受同源策略的限制,不能发送跨域请求;
不能发送二进制文件(如图片、视频、音频等),只能发送纯文本数据;
在发送和获取数据的过程中,无法实时获取进度信息,只能判断是否完成;

Level 2对Level 1 进行了改进,XMLHttpRequest Level 2中新增了以下功能:
可以发送跨域请求,在服务端允许的情况下;
支持发送和接收二进制数据;
新增formData对象,支持发送表单数据;
发送和获取数据时,可以获取进度信息;
可以设置请求的超时时间;

图片是XmlHttpRequest Level 2的兼容性

从图中可以看到:

IE8/IE9、Opera Mini 完全不支持xhr对象
IE10/IE11部分支持,不支持 xhr.responseType为json
部分浏览器不支持设置请求超时,即无法使用xhr.timeout
部分浏览器不支持xhr.responseType为blob

以上xhr兼容性描述是引用自https://segmentfault.com/a/11...

以下是我之前写的有进度条的文件上传的demo,里面有css样式,代码比较长。通过给xhr对象添加监听事件,比如beforeSend事件初始化进度条,progress事件返回上传进度等。




    
    
    
    
    
    
    
    运单上传
    


上传文件
提示:请上传excel文件


补充:有用xhr做过图片直传七牛。用canvas压缩了图片,该方法还是不兼容IE8,是用appcan做一个小项目的时候用过。附上代码。(需求是多图片上传,需要一张一张上传,并且如果有其中一张图片在上传时失败,则停止上传剩下的图片,如果全部上传成功,则提交整个表单,submitDone()方法就是提交表单,因为与本文没什么关系,就不写出来了。)

function putb64(dataArr) {
    var pic = dataArr[isSuc].substring(23); // pic是图片的base64编码
    var timestamp = (new Date()).valueOf();
    var url = "http://upload.qiniu.com/putb64/-1";
    var xhr = new XMLHttpRequest();
    xhr.open("POST", url, true);
    xhr.setRequestHeader("Content-Type", "application/octet-stream");
    xhr.setRequestHeader("Authorization", "UpToken " + $("input[name=token]").val());
    xhr.send(pic);
    xhr.onreadystatechange = function() {
        if (xhr.readyState == 4) {
            if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
                var data = $.parseJSON(xhr.responseText);
                key.push(data.key); ++isSuc;
                if (isSuc < baseArr.length) {
                    putb64(dataArr);
                } else if (isSuc == baseArr.length) {
                    submitDone();
                }

            } else {

                appcan.window.alert({
                    title : '',
                    content : xhr.responseText,
                    buttons : '确定'
                });
                stopLoading();
                toast('图片上传失败');
            }
        }
    }
}

附上图片转base64编码方法

var img = new Image();
img.src = imgArr[imgIndex]; //imgArr是图片数组
img.onload = function() {
    var canvas = document.createElement("canvas");
    canvas.width = img.width;
    canvas.height = img.height;

    var ctx = canvas.getContext("2d");
    ctx.drawImage(img, 0, 0);

    var dataURL = canvas.toDataURL("image/jpeg", 0.4); // 0.4就是图片压缩的程度
    baseArr.push(dataURL);
}

你可能感兴趣的:(文件上传,图片上传)