zoukankan      html  css  js  c++  java
  • 关于ajax分段上传文件实例~

    本来打算写的勤快一点的,谁知道最近好忙啊,忙着应聘的事情,这里突然想提一下自己的历程

    自己现在是一只大三狗,高中三年是玩过去了,上了一所省内普通的不能再普通的二本。不过在大学里还算的上勤奋,大一上在学生会搅搅水,大一下就开始在学校网络中心里面干活,网络维护是工作,编程是兴趣,基本上每天网络中心寝室两点一线,所以说还算得上勤奋。不过现在我自己算是明白,很多事情不是勤奋就好了的,方法不对,真的是事倍功半。自己之前学习东西都是瞎倒腾,看书,看视频,记笔记,写demo。看起来稀疏平常,但是自己缺点在于太好高骛远了。

    想起来一件好玩的事情,曾经网络中心内部需要搭建一个论坛,自己当时逮到就写,打算写一个在线交流的。想法很好是吧,可是当时的我压根就不知道web socket……我是如何实现的呢,无时无刻的不在用ajax。成功倒也成功了,只是觉得不是很值得,ajax确实可以一定的模拟web实时,不过会用尝试一下就行,真的要拿来做聊天室,写着累,别人用着也不方便,举个栗子就是判断别人在不在线。

    这段事件因为招聘复习基础,发现了自己太多太多不牢固的地方,以前的自己太过轻浮,现在回炉重造,任何东西都努力自己尝试尝试,自己加上一些想法,然后发表出来。就好比这次的Ajax分段上传文件。

    ——————————————————————————————————————————————————————————————————————————————

    回归正题,实现声明,UI无美化,美观强迫症的我就对不起你们了~

    html部分代码

    <div id="wrap">
            <form method="post" action="./test.php" enctype="multipart/form-data">
                <input type="file" name="file" id="f"></input>
            </form>
    </div>

    最简单的布局了,就是绕着一个input type='file'空间展开的,因为一切随简,所以没有加multiple="true"

     1 window.onload = function(){
     2     var oFile = document.getElementById('f');
     3     
     4     var fileSplitSize = 1024 * 1024;  //文件分段大小1M
     5     
     6     oFile.addEventListener('change', function(e){
     7         var files = this.files;
     8         
     9         var file = files[0];  //获得file对象
    10         
    11         var size = file.size,
    12             start = 0;
    13 
    14         var funUpload = function(){
    15 
    16             var data = new FormData();  //利用FormData对象模拟表单
    17             
    18             //data.append('name', encodeURIComponent(file.name));  //Ajax如果用GET方法必须要编码再传递,不过POST我测试出来不需要也可以诶
    19             data.append('name', file.name);
    20             data.append('file', file.slice(start, start + fileSplitSize));  //核心切割file文件,下面详细解释①
    21             data.append('start', '' + start);
    22             
    23             var xhr = new XMLHttpRequest();  //XMLHttpRequest 2.0对象
    24             
    25             xhr.open('post', './test.php', true);
    26             //xhr.setRequestHeader('Content-Type', 'multipart/form-data');  //这里千万不要加这句话,下面有原因②
    27             xhr.setRequestHeader('X_Requested_With', location.href.split("/")[3].replace(/[^a-z]+/g, '$'));
    28             xhr.send(data);
    29             
    30             xhr.onreadystatechange = function(){
    31                 if(xhr.readyState == 4){
    32                     if(xhr.status == 200){
    33                         if(start + fileSplitSize >= size){
    34                             alert(xhr.responseText);
    35                         }else{
    36                             alert('一次上传成功');
    37                             start += fileSplitSize;
    38                             funUpload();
    39                         }
    40                     }
    41                 }
    42             }
    43         }
    44         funUpload();
    45         
    46     }, false);
    47 }

    看①

    file对象继承Blob对象,不知道这两个对象的自行百度我就不解释了,算了还是贴一个图吧~

    其实此时file.slice(start, start + fileSplitSize)得到的结果是Blob对象,将它作为模拟的表单的file传递给服务器端

    再看②

    这个一定要注意,两张图就可以解释原因了

    如果你加了xhr.setRequestHeader('Content-Type', 'multipart/form-data');

    然后上传文件就会失败了,缺少boundary这分隔符

    再让我们看看正确的样子

    本人感觉这是一个坑。。因为本人栽进去一次。。希望别人注意

    前端部分完结,下面是PHP的,很简单

    define('ROOT', '.');
    
    $filename = ROOT . '/' . iconv('utf-8', 'gbk', $_POST['name']);  //转码这里千万要注意,否则中文名的话系统就会乱码①
            
    if($_POST['start'] == 0){
        
        $fp = fopen($filename, "w+");
        
        file_put_contents($filename, file_get_contents($_FILES[$name]['tmp_name']), FILE_APPEND);
        
        fclose($fp);
        
    }else{
        
        file_put_contents($filename, file_get_contents($_FILES[$name]['tmp_name']), FILE_APPEND);
        
    }
    
    echo $filename;

    看①

    通常我们的PHP脚本文件要么是Unicode(utf8)或者是ANSI(gbk),gbk兼容gb2312

    如果是Unicode编码(utf8),代码里的中文和系统是两种不同的编码,与系统打交道时,如创建中文名称的文件、文件夹等,需要转换编码。

    如果是ANSI编码(gbk、gb2312),代码里的中文和系统是系统的编码,不需要转换编码。

    结语:其实这个分段传输可拓展性还是很高的啊,比如断点续传等等~我在这里就不演示啦~

    最近在好好地读ECMA5,正确整理一点资料早点发出来~

  • 相关阅读:
    IDEA连接 Oracle数据库
    什么是混合云备份
    什么是阿里云ACA认证
    什么是阿里云ACE认证
    什么是轻量应用服务器
    什么是时序时空数据库TSDB
    什么是数据管理DMS
    什么是分析型数据库PostgreSQL版
    阿里云多端小程序
    阿里云云计算ACP专业认证考试
  • 原文地址:https://www.cnblogs.com/constructor/p/4415859.html
Copyright © 2011-2022 走看看