瀏覽器如何處理文件,文件的上載與下載究竟是怎麼回事?
前端的各類處理方式
- 傳統flash上傳
- 新增iframe框ajax上載
- 表單數據提交
- HTML5的新工具——File API前端
咱們下面依次講一下它們的原理,主要是後二者和後端如何處理node
沒有了解過,不作評論ajax
經過新建一個隱藏的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,指定了不同的編碼類型。緩存
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.open(option.method,option.action); xhr.overridemimeType('..');//設定content-type xhr.send(form);
能夠把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; };
瀏覽器的文件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文件上傳原理詳解,有興趣的能夠閱讀。