zoukankan      html  css  js  c++  java
  • 使用 html5 FileReader 获取图片, 并异步上传到服务器 (不使用 iframe)

    原理:

    1.使用FileReader 读取图片的base64编码

    2.使用ajax,把图片的base64编码post到服务器。

    3.根据接收到post的数据分析图片的类型(jpg,gif,png),并把base64_decode后的数据生成对应类型的图片文件。

    html:

    [javascript] view plaincopy在CODE上查看代码片派生到我的代码片

    1. <!DOCTYPE HTML PUBLIC>  
    2. <html>  
    3.  <head>  
    4.   <meta charset="utf-8">  
    5.   <script src="//code.jquery.com/jquery-1.11.0.min.js"></script>  
    6.   <title>使用html5 FileReader获取图片,并异步上传到服务器(not iframe)</title>  
    7.   
    8.   <style type="text/css">  
    9.     body{margin: 0px; background:#f2f2f0;}  
    10.     p{margin:0px;}  
    11.     .title{color:#FFFF00; background:#000000; text-align:center; font-size:24px; line-height:50px; font-weight:bold;}  
    12.     .file{position:absolute; 100%; font-size:90px;}  
    13.     .filebtn{display:block; position:relative; height:110px; color:#FFFFFF; background:#06980e; font-size:48px; line-height:110px; text-align:center; cursor:pointer; border: 3px solid #cccccc;}  
    14.     .filebtn:hover{background:#04bc0d;}  
    15.     .showimg{margin:10px auto 10px auto; text-align:center;}  
    16.   </style>  
    17.   
    18.   <script type="text/javascript">  
    19.   window.onload = function(){  
    20.   
    21.     // 选择图片  
    22.     document.getElementById('img').onchange = function(){  
    23.   
    24.         var img = event.target.files[0];  
    25.   
    26.         // 判断是否图片  
    27.         if(!img){  
    28.             return ;  
    29.         }  
    30.   
    31.         // 判断图片格式  
    32.         if(!(img.type.indexOf('image')==0 && img.type && /.(?:jpg|png|gif)$/.test(img.name)) ){  
    33.             alert('图片只能是jpg,gif,png');  
    34.             return ;  
    35.         }  
    36.   
    37.         var reader = new FileReader();  
    38.         reader.readAsDataURL(img);  
    39.   
    40.         reader.onload = function(e){ // reader onload start  
    41.             // ajax 上传图片  
    42.             $.post("server.php", { img: e.target.result},function(ret){  
    43.                 if(ret.img!=''){  
    44.                     alert('upload success');  
    45.                     $('#showimg').html('<img src="' + ret.img + '">');  
    46.                 }else{  
    47.                     alert('upload fail');  
    48.                 }  
    49.             },'json');  
    50.         } // reader onload end  
    51.     }  
    52.   
    53.   }  
    54.   </script>  
    55.   
    56.  </head>  
    57.   
    58.  <body>  
    59.   <p class="title">使用html5 FileReader获取图片,并异步上传到服务器(not iframe)</p>  
    60.   <p><input type="file" class="file" id="img"><label class="filebtn" for="img" title="JPG,GIF,PNG">请选择图片</label></p>  
    61.   <p class="showimg" id="showimg"></p>  
    62.  </body>    
    63. </html>  

    server.php

    [php] view plaincopy在CODE上查看代码片派生到我的代码片

    1. <?php  
    2. $img = isset($_POST['img'])? $_POST['img'] : '';  
    3.   
    4. // 获取图片  
    5. list($type, $data) = explode(',', $img);  
    6.   
    7. // 判断类型  
    8. if(strstr($type,'image/jpeg')!==''){  
    9.     $ext = '.jpg';  
    10. }elseif(strstr($type,'image/gif')!==''){  
    11.     $ext = '.gif';  
    12. }elseif(strstr($type,'image/png')!==''){  
    13.     $ext = '.png';  
    14. }  
    15.   
    16. // 生成的文件名  
    17. $photo = time().$ext;  
    18.   
    19. // 生成文件  
    20. file_put_contents($photo, base64_decode($data), true);  
    21.   
    22. // 返回  
    23. header('content-type:application/json;charset=utf-8');  
    24. $ret = array('img'=>$photo);  
    25. echo json_encode($ret);  
    26. ?>  

    File API

    由于JavaScript对用户上传的文件操作非常有限,尤其是无法读取文件内容,使得很多需要操作文件的网页不得不用Flash这样的第三方插件来实现。

    随着HTML5的普及,新增的File API允许JavaScript读取文件内容,获得更多的文件信息。

    HTML5的File API提供了FileFileReader两个主要对象,可以获得文件信息并读取文件。

    下面的例子演示了如何读取用户选取的图片文件,并在一个<div>中预览图像:

    图片预览:

    var
        fileInput = document.getElementById('test-image-file'),
        info = document.getElementById('test-file-info'),
        preview = document.getElementById('test-image-preview');
    // 监听change事件:
    fileInput.addEventListener('change', function () {
        // 清除背景图片:
        preview.style.backgroundImage = '';
        // 检查文件是否选择:
        if (!fileInput.value) {
            info.innerHTML = '没有选择文件';
            return;
        }
        // 获取File引用:
        var file = fileInput.files[0];
        // 获取File信息:
        info.innerHTML = '文件: ' + file.name + '<br>' +
                         '大小: ' + file.size + '<br>' +
                         '修改: ' + file.lastModifiedDate;
        if (file.type !== 'image/jpeg' && file.type !== 'image/png' && file.type !== 'image/gif') {
            alert('不是有效的图片文件!');
            return;
        }
        // 读取文件:
        var reader = new FileReader();
        reader.onload = function(e) {
            var
                data = e.target.result; // 'data:image/jpeg;base64,/9j/4AAQSk...(base64编码)...'            
            preview.style.backgroundImage = 'url(' + data + ')';
        };
        // 以DataURL的形式读取文件:
        reader.readAsDataURL(file);
    });
    

    上面的代码演示了如何通过HTML5的File API读取文件内容。以DataURL的形式读取到的文件是一个字符串,类似于data:image/jpeg;base64,/9j/4AAQSk...(base64编码)...,常用于设置图像。如果需要服务器端处理,把字符串base64,后面的字符发送给服务器并用Base64解码就可以得到原始文件的二进制内容。

    回调

    上面的代码还演示了JavaScript的一个重要的特性就是单线程执行模式。在JavaScript中,浏览器的JavaScript执行引擎在执行JavaScript代码时,总是以单线程模式执行,也就是说,任何时候,JavaScript代码都不可能同时有多于1个线程在执行。

    你可能会问,单线程模式执行的JavaScript,如何处理多任务?

    在JavaScript中,执行多任务实际上都是异步调用,比如上面的代码:

    reader.readAsDataURL(file);
    

    就会发起一个异步操作来读取文件内容。因为是异步操作,所以我们在JavaScript代码中就不知道什么时候操作结束,因此需要先设置一个回调函数:

    reader.onload = function(e) {
        // 当文件读取完成后,自动调用此函数:
    };
    

    当文件读取完成后,JavaScript引擎将自动调用我们设置的回调函数。执行回调函数时,文件已经读取完毕,所以我们可以在回调函数内部安全地获得文件内容。

    转载于:https://my.oschina.net/dawd/blog/906803

  • 相关阅读:
    PAIRING WORKFLOW MANAGER 1.0 WITH SHAREPOINT 2013
    Education resources from Microsoft
    upgrade to sql server 2012
    ULSViewer sharepoint 2013 log viewer
    Top 10 Most Valuable Microsoft SharePoint 2010 Books
    讨论 Setsockopt选项
    使用 Alchemy 技术编译 C 语言程序为 Flex 可调用的 SWC
    Nagle's algorithm
    Nagle算法 TCP_NODELAY和TCP_CORK
    Design issues Sending small data segments over TCP with Winsock
  • 原文地址:https://www.cnblogs.com/twodog/p/12140491.html
Copyright © 2011-2022 走看看