Web的文件處理


前言

瀏覽器如何處理文件,文件的上載與下載究竟是怎麼回事?
前端的各類處理方式
- 傳統flash上傳
- 新增iframe框ajax上載
- 表單數據提交
- HTML5的新工具——File API前端

咱們下面依次講一下它們的原理,主要是後二者和後端如何處理node

flash上傳

沒有了解過,不作評論ajax

iframe框上傳

經過新建一個隱藏的iframe框,把數據放到這個iframe框架裏,而後把它提交到服務器端處理,服務器返回的信息也是有iframe框調用父框架的方法處理。總之,是很坑爹的。後端

表單數據提交

重點有兩個,一個是FormData的數據對象,一個是level2 的XHttpRequest對象。瀏覽器

表單數據

var form= new FormData();
form.append(field,file,filename);
//field是表單裏的key,就相似於通常表單裏的name,file文件對象,filename是傳送至服務器裏的文件名,通常缺省

只要FormData裏含有文件時,上傳時enctype就是multipart/form-data而非通常時的application/x-www-form-urlencoded,指定了不同的編碼類型。緩存

XHttpRequest對象

建立xhr對象
if (typeof XMLHttpRequest !== 'undefined') {
       xhr = new XMLHttpRequest();
} else {
         var v = [
            "Microsoft.XmlHttp",
            "MSXML2.XmlHttp.5.0",
            "MSXML2.XmlHttp.4.0",
            "MSXML2.XmlHttp.3.0",
            "MSXML2.XmlHttp.2.0"
         ];
         for (var i=0; i < v.length; i++){
             try {
                  xhr = new ActiveXObject(v[i]);
                  break;
                 } catch (e){}
             }
         }
         return xhr;
xhr發起請求
xhr.open(option.method,option.action);
xhr.overridemimeType('..');//設定content-type
xhr.send(form);
xhr處理事件

能夠把xhr對象當原生js對象看待,其方法的調用都符合原生對象的習慣和規律服務器

xhr.addEventlistener('progress',function(evt){
    if(evt.lengthComputable){
      var complete=evt.loaded/evt.total | 0;
    }
});
//progress事件在一次請求回話中定時觸發,經常使用作進度條
//最重要的事件是readystatechange,xhr對象有0,1,2,3,4五個狀態
//當狀態爲4的時候,回話結束,不管錯誤仍是得到響應
//狀態爲4時,status==200說明從服務器成功得到響應
xhr.onreadystatechange=function(evt){
    if(this.readystate!==4) return;
    if(this.state==200){success..}
    else fail;
};
xhr的重要變量
  • xhr.state
  • xhr.readystatechange
  • xhr.responseText,從服務器獲得的響應,純文本格式,應該進一步解析

File API

瀏覽器的文件API只能讀本地文件而不能寫本地文件,其中最重要的是FileReader。app

建立與讀取

var reader=new FileReader();
reader.readAsBinaryString(file);
reader.readAsText(file);
reader.readAsDataURL(file);
//DataURL是一種指向瀏覽器緩存的base64編碼的字符串,能夠用來預覽圖片

事件處理

其處理機制也是與原生js對象一致的框架

reader.onload//成功讀取
reader.onprogress//基本與前面的xhr的progress一致
reader.onloadend//不管是否成功,結束使=時均會觸發
reader.onloadend=function(evt){
    if(reader.error) return error;
    return evt.target.result;
    //evt.target指向reader,用this.result也應該能夠
};

上傳操做

xhr將類型設置爲二進制流
xhr.send(reader.result);

可是我在node的後端沒有找到好的插件來解析req,致使雖然我驗證了這種方式真的上傳了文件(大小),但沒有實現文件寫到服務器磁盤,我我的認爲這纔是文件上傳將來的主要模式。ide

後端處理

req=請求頭+請求體
請求頭會被當即解析,而請求體不會
請求體中不只包含了文件的內容,還有文件的信息,實際上文件是一個可讀流對象,還有它的各類屬性,咱們解析以後才能把文件與文件,文件內容與文件信息區分開來
對於通常的文本編碼,只要這樣作就能夠了

var post='';
req.on('data',function(chunk){
    post+=querystring.parse(chunk);
});

咱們能夠輕易地看到內容
單對於二進制數據就沒有這麼簡單了,文件與文件之間是有特定的分隔符的,關於這一點,cnode上有一篇文章講的很好,文章名是node-post文件上傳原理詳解,有興趣的能夠閱讀。

相關文章
相關標籤/搜索