zoukankan      html  css  js  c++  java
  • 前端文件上传-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
    Content-Disposition: form-data; name="file"; filename="1.png"
    Content-Type: '+_filePathHash[_filePath]+'
    
    ';
        var end = '
    --------------------------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设置成一个极大,让他所有不一样的东西,都超出去,这样就是在能改动的区域改动了

  • 相关阅读:
    MIME类型大全
    Asp.net中解决“请求超时”的问题
    C#日期函数所有样式大全
    [转]Oracle数据关联查询
    convert时间格式转换参数表 [收藏]
    vs2008安装失败。解决办法。部分。
    asp.net获取web.config配置信息
    jQuery UI Dialog控件中的表单无法正常提交的解决方法
    控制Button在数据验证成功才执行后台方法
    关于使用DataTable.Compute()方法时报“聚合参数中的语法错误: 需要具有可能的“Child”限定符的单个列参数。”
  • 原文地址:https://www.cnblogs.com/10manongit/p/12814480.html
Copyright © 2011-2022 走看看