2009-07-07 84 views
22

我試圖加載一個圖像客戶端和base64編碼服務器返回的字節,以傳遞它來執行一些處理。 IE有一個XMLHttpRequest對象的RequestBody屬性,但我似乎無法使用它,並且RequestText被截斷。在Firefox中,RequestText在那裏,但似乎損壞。如何使用Javascript和XMLHttpRequest加載二進制圖像數據?

+0

經過幾天的努力,我能夠完成這項工作,儘管互聯網上進行這種二元操作的信息相當稀少。我認爲這可能對其他人有用,特別是在處理數據URI時,所以我詳細介紹了我的工作:[http://emilsblog.lerch.org/2009/07/javascript-hacks-using-xhr-to- load.html](HTTP://emilsblog.lerch。org/2009/07/javascript-hacks-using-xhr-to-load.html) – 2009-07-07 22:01:36

回答

0

您可以讓服務器返回base64文本,而不是執行該編碼客戶端。

例如,(在ASP.NET中)可以將對/ImageAsBase64.ashx?file=/images/myimage.png的請求編碼爲讀取文件,base64對其進行編碼並將其作爲響應進行流式傳輸。

它真的是非常的PHP或任何同樣的事情。

+0

不幸的是,在這種情況下無法工作 - 我需要某些COTS軟件的數據,而且它沒有base64選項。 – 2009-07-07 22:06:18

1

如果您使用COTS,你總是可以建立一箇中間網關,其中提出要求和轉化的(Base64在這種情況下,編碼)到的東西被返回給客戶端之前更可口。

+1

我其實已經試過了;但是,圖像是特定於用戶會話的,我無法將軟件僞裝成認爲服務器是同一用戶會話的一部分。 – 2009-07-08 13:42:07

12

下面是我做到的。在回答中提供給其它SO問題

這種技術,但它也與此有關。

我不想base64編碼任何東西。我想通過Javascript下載並解析瀏覽器中的二進制文件,而不需要修改服務器來專門對其進行編碼。我發現在Firefox中,通過強制通過overrideMimeType()響應的MIME類型,我可以使用XMLHttpRequest.responseText。在IE上,它的不同之處在於:

  • responseText IE在第一個零處截斷。對於二進制流,這是一個很大的問題。

  • 沒有XMLHttpRequest.overrideMimeType(),強制IE將二進制流視爲文本。

  • 雖然有一個專門設計用於二進制數據流的XMLHttpRequest.responseBody(僅限IE!),令人瘋狂的是,該屬性在Javascript中不可用。

因此,需要的是IE的responseBody財產轉換成看起來像responseText從Firefox,用MIME類型強制的事情。這可以使用注入的VBScript。

爲了讓跨瀏覽器,你只是需要收拾在有條件的瀏覽器特定的邏輯。這是我用什麼:

// one-time code 
if(/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)) { 
    var IEBinaryToArray_ByteStr_Script = 
    "<!-- IEBinaryToArray_ByteStr -->\r\n"+ 
    "<script type='text/vbscript'>\r\n"+ 
    "Function IEBinaryToArray_ByteStr(Binary)\r\n"+ 
    " IEBinaryToArray_ByteStr = CStr(Binary)\r\n"+ 
    "End Function\r\n"+ 
    "Function IEBinaryToArray_ByteStr_Last(Binary)\r\n"+ 
    " Dim lastIndex\r\n"+ 
    " lastIndex = LenB(Binary)\r\n"+ 
    " if lastIndex mod 2 Then\r\n"+ 
    "  IEBinaryToArray_ByteStr_Last = Chr(AscB(MidB(Binary, lastIndex, 1)))\r\n"+ 
    " Else\r\n"+ 
    "  IEBinaryToArray_ByteStr_Last = "+'""'+"\r\n"+ 
    " End If\r\n"+ 
    "End Function\r\n"+ 
    "</script>\r\n"; 

    // inject VBScript 
    document.write(IEBinaryToArray_ByteStr_Script); 
} 


// each time you make a request for a binary resource: 
var req = (function() { 
    if (window.XMLHttpRequest) { 
     return new window.XMLHttpRequest(); 
    } 
    else { 
     try { 
      return new ActiveXObject("MSXML2.XMLHTTP"); 
     } 
     catch(ex) { 
      return null; 
     } 
    } 
})(); 

var fileContents = ""; 
var filesize = -1; 
var readByteAt = function(i){ 
    return fileContents.charCodeAt(i) & 0xff; 
}; 

req.open("GET", url, true); 

if(/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)) { 
    // IE-specific logic here 
    // helper to convert from responseBody to a "responseText" like thing 
    var convertResponseBodyToText = function (binary) { 
     var byteMapping = {}; 
     for (var i = 0; i < 256; i++) { 
      for (var j = 0; j < 256; j++) { 
       byteMapping[ String.fromCharCode(i + j * 256) ] = 
        String.fromCharCode(i) + String.fromCharCode(j); 
      } 
     } 
     var rawBytes = IEBinaryToArray_ByteStr(binary); 
     var lastChr = IEBinaryToArray_ByteStr_Last(binary); 
     return rawBytes.replace(/[\s\S]/g, 
           function(match) { return byteMapping[match]; }) + lastChr; 
    }; 

    req.setRequestHeader("Accept-Charset", "x-user-defined"); 
    req.onreadystatechange = function(event){ 
     if (req.readyState == 4) { 
      if (req.status == 200) { 
       fileContents = convertResponseBodyToText(req.responseBody); 
       fileSize = fileContents.length-1; 
       // invoke a callback here, if you like... 
      } 
      else{ 
       alert("download failed, status " + req.status); 
      } 
     } 
    }; 
    req.send(); 

} else { 
    // ff/Gecko/Webkit specific stuff here 
    req.onreadystatechange = function(aEvt) { 
     if (req.readyState == 4) { // completed 
      if(req.status == 200){ // status == OK 
       fileContents = binStream.req.responseText; 
       filesize = fileContents.length; 
       // invoke a callback here, if you like... 
      } 
      else { 
       alert("download failed, status " + req.status); 
      } 
     } 
    }; 
    // coerce response type 
    req.overrideMimeType('text/plain; charset=x-user-defined'); 
    req.send(null); 
} 

...然後調用readByte(i)在二進制文件中的第i個位置拿到字節。

祝你好運。

Credit to Miskun爲VBScript轉換邏輯。

相關問題