2017-12-17

將 json 檔 get 回來時如何建立為 web api 的 object file 型

最近很專心在 javascript 中…

有一個 case ,它裡面原先提供的 function 中,本來是需要你從前端使用 form file 的方式選擇檔案後,再丟入它提供的 function ,這個 function 會依傳入的 form file 檢查相關的 meta …

但這個 case 有一個東西,它是要經由網路取得的 json 檔,然後丟進這個 function 中來檢查…

所以我假設原 function 是
var checkfile = function ( file ) {
   var filename = file.name;
   var extension = filename.split( '.' ).pop().toLowerCase();
   ....
   ....
}
如果是經由 form file 來傳送的,此 checkfile( form file ),是可以正常執行的…



但,現在來源不是 form file ,而是一個 url ,如果直接 checkfile( url ) 的話,在 checkfile 的 function 中的 file.name 就會先出錯了…因為 checkfile( file ) 的 file 是一個 File Object ,而不是純字串,而且在 checkfile( file ) 中也有實際要對此 File Object 進行處理,所以也不能只傳字串而已…

所以,因為如此,等於要把 url file 確實傳輸回來後再進行處理…

我們先看一下一般使用 javascript 抓檔怎麼做
var _file = '';
var getfile = new XMLHttpRequest();
getfile.open( 'GET', 'url' );
getfile.onload = function () {
   if ( this.status === 200 ) {
      _file = this.response;
   }
};
getfile.send(null);
上述的作法,最後的 _file 會得到該 url 檔案的「內容」,此 _file 的型態會是 string ,也就是說上述的方式針對「文字 text/plain 型態的檔案」會比較好,像我標題說的 json 檔。

但以上述的方式,再加上我前面的說明會知道, checkfile( file ) 的 file 必須是 File Object ,所以必須要將 _file 由 string 變為 File Object ,這時可以變為以下的方式
var _file = '';
var getfile = new XMLHttpRequest();
getfile.open( 'GET', 'url' );
getfile.responseType = 'blob';
getfile.onload = function () {
   if ( this.status === 200 ) {
      _file = new File( [ this.response ], 'customFileName.json', { type: 'application/json' });
   }
};
getfile.send(null);
如上述,此  _file 就可以被建立為一個 File Object ,並有一個臨時檔名「customFileName.json」,還有新的 meta 的 type 資料為「application/json」了,這樣再把 _file 送入 checkfile( _file ) 去就都 ok 了

但我上面的方式有特別標注了兩個色塊

  • reponseType = 'blob';
    如果你 get 的檔案是如我前面說的是「純文字內容」的檔案,那這一行可以不用使用,丟進 new File 一樣可以被建立為 File Object ,但我是建議還是使用這個方式,這樣可以讓抓回來的檔案內容會是一個 Blob Object ,Blob 是一個二進位值的物件,幾乎可以等同是「原始檔案」,而依照原生定義 File Object 的生成是由 blob object 過來的,也就是從原始檔案轉換而來,比較不容易出錯
    而 responseType  是指定你 get 來的東西是以 blob 型式回傳,當然,你如果不指定 responseType ,也可以去建立一個 blob object 後存放內容…但,我認為有原生就可以指定的方式,其實不用去做容易造成出錯的方式…所以 responseType 有提供就用唄
  • [ this.response ]
    我會標起這個,主要原因是因為,我在使用這個方式時,我原本是用「new File( this.response, 'customFileName.json', { type: 'application/json' } );」的,但都會出現「Failed to construct 'File': The provided value cannot be converted to a sequence.」的錯誤,我一直想不透,後來去找了 MDN 文件來看,發現,File Object 雖然是將 blob 資料丟過去,但必須是要用 Array object 存放著 blob 的資料才能轉換…所以就 [ ] 
以上

沒有留言: