使用XMLHttpRequest和FileReader上传二进制文件whyle设置自定义内容类型和边界

问题描述:

我试图使用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)?

我找到了答案,以我的(第一部分)问题,由于这一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])]));