2017-05-26 45 views
2

我試圖使用XMLHttpRequest和FileReader將(DICOM)二進制文件上載到服務器。使用XMLHttpRequest和FileReader上傳二進制文件whyle設置自定義內容類型和邊界

根據DICOM標準的內容類型搞亂來multipart/related;type=application/dicom定義和請求負載必須Content-Type:application/dicom再次,我設法以某種方式構建結構與此代碼:

let boundary = Math.random().toString().substr(2); 
    let reader = new FileReader(); 
    reader.readAsBinaryString(fileList[0]); 

    reader.onload = function(e) { 

     var xmlHttpRequest = new XMLHttpRequest(); 
     xmlHttpRequest.open("POST", "myurl", true); 
     var dashes = '--'; 
     var crlf = "\r\n"; 
     if (fileList[0].type == ''){ 
      filetype = 'application/dicom'; 
     } else { 
      filetype = fileList[0].type; 
     } 
     let content = e.target["result"]; 
     var data = dashes + boundary + crlf + "Content-Type: " + filetype + crlf + crlf + content + crlf + dashes + boundary + dashes; 
     xmlHttpRequest.setRequestHeader("Content-Type", "multipart/related;type=application/dicom;boundary=" + boundary+";"); 
     xmlHttpRequest.setRequestHeader("Accept", "application/dicom+json"); 
     xmlHttpRequest.send(data); 
    }; xmlHttpRequest.send(data); 
     }; 

的問題這種方法似乎是XMLHttpRequest進行UTF-8編碼,並且破壞了二進制數據(請參閱this後)。

  • 問題是如何使用reader.readAsArrayBuffer()並設置正文的內容類型和邊界?或
  • 如何防止XMLHttpRequest進行UTF-8編碼?

我的第二個問題是如何用這種方法處理大文件(大約1TB)?

回答

2

我找到了答案,以我的(第一部分)問題,由於這一post,票數是我的代碼現在:

var boundary = Math.random().toString().substr(2); 
var reader = new FileReader(); 
reader.readAsArrayBuffer(fileList[0]); 
reader.onload = function(e) { 
    var xmlHttpRequest = new XMLHttpRequest(); 
    xmlHttpRequest.open("POST", "myurl", true); 
    var dashes = '--'; 
    var crlf = "\r\n"; 
    if (fileList[0].type == ''){ 
     filetype = 'application/dicom'; 
    } else { 
     filetype = fileList[0].type; 
    } 
    var content = e.target["result"]; 
    var dataView = new DataView(e.target["result"]); 
    var postDataStart = dashes + boundary + crlf + "Content-Disposition: form-data;" + "name=\"file\";" + "filename=\"" + encodeURIComponent(fileList[0].name) + "\"" + crlf + "Content-Type: " + filetype + crlf + crlf; 
    var postDataEnd = crlf + dashes + boundary + dashes; 
    var size = postDataStart.length + dataView.byteLength + postDataEnd.length; 
    var uint8Array = new Uint8Array(size); 
    var i = 0; 

    for (; i < postDataStart.length; i++) { 
      uint8Array[i] = postDataStart.charCodeAt(i) & 0xFF; 
    } 
    for (let j = 0; j < dataView.byteLength; i++, j++) { 
      uint8Array[i] = dataView.getUint8(j); 
    } 
    for (let j = 0; j < postDataEnd.length; i++, j++) { 
     uint8Array[i] = postDataEnd.charCodeAt(j) & 0xFF; 
    } 
    var payload = uint8Array.buffer; 
    xmlHttpRequest.setRequestHeader("Content-Type", "multipart/related;type=application/dicom;boundary=" + boundary+";"); 
    xmlHttpRequest.setRequestHeader("Accept", "application/dicom+json"); 
    xmlHttpRequest.send(payload); 
}; 

編輯:

我發現了另一個解決方案,它的工作有更大文件作爲可用的RAM,並且正在流式傳輸文件,而不是首先將所有文件加載到RAM中:

var boundary = Math.random().toString().substr(2); 
    var xmlHttpRequest = new XMLHttpRequest(); 
    xmlHttpRequest.open("POST", "myurl", true); 
    var dashes = '--'; 
    var crlf = "\r\n"; 
    filetype = fileList[0].type; 

    var postDataStart = dashes + boundary + crlf + "Content-Disposition: form-data;" + "name=\"file\";" + "filename=\"" + encodeURIComponent(fileList[0].name) + "\"" + crlf + "Content-Type: " + filetype + crlf + crlf; 
    var postDataEnd = crlf + dashes + boundary + dashes; 

    xmlHttpRequest.setRequestHeader("Content-Type", "multipart/related;type=application/dicom;boundary=" + boundary+";"); 
    xmlHttpRequest.setRequestHeader("Accept", "application/dicom+json"); 
    xmlHttpRequest.send(new Blob([new Blob([postDataStart]),fileList[0], new Blob([postDataEnd])])); 
相關問題