前端文件上传-javascript-ajax

誊写是为了更好的影象。

计划一:form表单上传

该计划长处是支撑好,瑕玷革新页面。

<form action="url"  method="post" enctype="multipart/form-data">
    <input type="file" name="file"><input type="submit" value="提交">
</form>  

道理:enctype就是form上传文件的重点。

形貌
application/x-www-form-urlencoded默许。在发送前对一切字符举行编码(将空格转换为 “+” 标记,特别字符转换为 ASCII HEX 值)
multipart/form-data不对字符编码。当运用有文件上传控件的表单时,该值是必须的
text/plain将空格转换为 “+” 标记,但不编码特别字符

计划二:form表单上传-优化计划一瑕玷

该计划的长处也是支撑好,瑕玷是不支撑跨域。

<form action="url"  method="post" enctype="multipart/form-data" target="iframe">
    <input type="file" name="file"><input type="submit" value="提交">
</form>

道理:经由过程target把相应指向一个iframe页面,以后拿到返回数据。

形貌
_blank在新窗口/选项卡中翻开
_self默许, 在统一框架中翻开
_parent在父框架中翻开。
_top在全部窗口中翻开
framename在指定的 iframe 中翻开

计划三:ajax上传-优化计划二瑕玷

该计划的瑕玷兼容问题-caniuse,兼容有两个方向一是低版本ie不支撑CORS跨域,一个就是input新加的Files。长处就是异步,进度条,推断大小,处置惩罚,跨域。

var file = input.files[0];
var xhr = new XMLHttpRequest();
if (xhr.upload) {
    xhr.upload.addEventListener("progress", function(e) {
        console.log(file, e.loaded, e.total);
    }, false);
    // 文件上传胜利或是失利
    xhr.onreadystatechange = function(e) {
        if (xhr.readyState == 4) {
            if (xhr.status == 200) {
                console.log('胜利', xhr.responseText)
            } else {
                console.log('失利')    
            }
        }
    }
    // 最先上传
    xhr.open("POST", 'url', true);
    xhr.send(file);
}

计划四:ajax-formData上传-多字段多文件;

该计划基础同上,只不过运用了FormData,瑕玷就是formData的兼容

var formData = new FormData();
formData.append('file', input.files[0]);
xhr.send(formData);

其他计划:

1. SWFupload Flash上传
2. jquery.form.js 其他插件上传

需求一:拖拽上传

运用drop事宜,猎取e.dataTransfer

document.querySelector('body').addEventListener("drop", (e)=>{
    e.preventDefault();//不写的话,就翻开了
    console.log(e.dataTransfer.files[0])
});

需求二:截图-粘贴-上传

运用paste事宜,猎取e.clipboardData

document.querySelector('body').addEventListener("paste", (e)=>{
    e.preventDefault();//不写的话,就翻开了
    console.log(e.clipboardData.files[0])
});

需求三:base64转换上传

场景发生在,一个和客户端交互的情况下,客户端挑选的图片以后返给我了一个base64,让我上传这个,而且接口那里还不改,就要文件。代码写的比较烦琐,实在也用不了这么多东西,当时也是第一次打仗atobBlobArrayBuffer这些东西,就写成如许了。

  function(data){
    var _str = atob(data.base64Str)
    var _filePath = ((data.filePath.match(/.(jpg|jpeg|png|bmp)$/) || [])[1] || 'png').toLowerCase();
    var _filePathHash = {
        jpg:'image/jpeg',jpeg:'image/jpeg',png: 'image/png',bmp:'application/x-bmp',
    }
    var pre = '--------------------------1\r\nContent-Disposition: form-data; name="file"; filename="1.png"\r\nContent-Type: '+_filePathHash[_filePath]+'\r\n\r\n';
    var end = '\r\n--------------------------1--';
    var buffer = new ArrayBuffer(_str.length);
    var uint8 = new Uint8Array(buffer);
    for(var i in _str){
        uint8[i] = _str.charCodeAt(i);
    }
    var blob = new Blob([pre, uint8, end], {type: _filePathHash[_filePath]});
    var oReq = new XMLHttpRequest();
    oReq.open("POST", "url", true);
    oReq.setRequestHeader("Content-Type", "multipart/form-data; boundary=------------------------1")
    oReq.onreadystatechange=function(){if (oReq.readyState==4 && oReq.status==200){console.log(oReq.responseText); }
    oReq.send(blob);

需求四

上传一般来说都是要写款式的,不能说光是默许的input款式就ok,然则呢,款式又不是那末太好写,我们怎么办呢?

计划一

label标签的for去触发input的单击,如许不就好了吗?input的款式不好写,那我们把他藏起来,给label写款式。

计划二

input[type=file]左侧是一个input右侧是个按钮,实际上是按钮的款式不好改,那末我们表面包裹一层overlfow:hidden,然后给input设置成一个极大,让他一切不一样的东西,都超出去,如许就是在能修改的地区修改了

    原文作者:linong
    原文地址: https://segmentfault.com/a/1190000014234901
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞