2013-05-17 55 views
2

簡而言之,我想將圖像的二進制數據發送到我的處理程序,它將以字節數組的形式保存在數據庫中。閱讀我的JavaScript使用readAsBinaryString(f)文件輸入的值,我會得到的輸出是這樣的:FileReader.readAsBinaryString返回二進制文件還是基於ASCII的字符集?

GIF89a,úæÿÿÿ2c½3fÌ Smaäµééúþc«T.[ÈéùAtεÚõ[ãXßÆî*[µc³8Ûõüÿfj¥æ§ÈïÛå÷ËØñI}ÓQ× 
*\»q£E}Ûÿå§ÓõþÿIÛv¤Þ´Åè«æ ³][us¬çAy×MÞ,a½«ÔóZÝL2äëùQ×(Eq<pË5V¨·ÏIÓ¨»åQßY¥3bØÈ 
æ¬z³é<uÓ3£ÎñE¾á÷RÛR¢K­®ÎØØìÍAtÓÑÔØrÀ-hݪÑïôõüR|ÎäóÖUËåæçXÔw»^s®ëI}ÛQ}ÔEÛ·Îñ½Óêd»Ì 
ÌëöåóôöÖàñE×Cr¿C¤3óúëLÍYÜ3fõûöÑðû Øûÿõw²ñ`ª»ßÀy|Á¿ÃIuÔM×ûñû{¹R4¼ìe¡äl«ç!ÿNETSCA 
PE2.0!ÿXMP DataXMP<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpm 
eta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.3-c011 66.145661, 2012/02 
/06-14:56:27 // etc.. 

這些數據是通過AJAX發送:

$.ajax({ 
    url: theUrl, 
    type: 'POST', 
    data: { Image: image } // image = data above 
}); 

這是一個二進制字符串?當我將這個字符串發送到我的處理程序(IHttpHandler)時,爲了將其存儲到字節數組中,如果將編碼設置爲ISO-8859-1,則只能獲取字節。

public void ProcessRequest (HttpContext aContext) 
{ 
    // This works as long as requestValidationMode = "2.0" in web.config 
    // Is there a way to bypass HttpRequestValidationException just on 
    // THIS data? 
    byte[] imageBytes = System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(_Context.Request["Image"]); 

    //... 
} 

這是正常的嗎?這也會引發HttpRequestValidationException(從..中檢測到潛在危險的Request.Form值)。我寧願不改變requestValidationMode,因爲它打開XSS,那麼如何逃脫二進制字符串? Base64編碼是否覆蓋了這一點,如果是的話,處理程序中的Base64轉換是否包含有關其數據類型的元數據?

+0

還有另一種方法http://stackoverflow.com/questions/3436398/convert-a-binary-string-representation-to-a-byte-array – stuartd

+0

感謝您的迴應,stuartd。我的問題是我的初始「二進制字符串」不表示爲1s和0s,就像上面的代碼片段,顯然不是二進制的,*我認爲*。爲什麼'readAsBinaryString'返回那*作爲*?那是我不熟悉的另一種二進制形式嗎? – Josh

+0

這看起來像'Assembly'給我。這本身就是奇怪的。 – Brian

回答

7

這真的有助於看到你在做什麼代碼,這就是爲什麼我asked你來顯示它。我猜代碼看起來是這樣的:

var f = $("image").files[0]; 
var reader = new FileReader(); 
reader.readAsBinaryString(f); 
var image = reader.result; 

$.ajax({ 
    url: theUrl, 
    type: 'POST', 
    data: { Image: image } 
}); 

現在,當你說:

我會得到的輸出是這樣的:

GIF89a,úæÿÿÿ2c½3... 

Is我的輸出[... ]二進制數據?

嗯是的,但你可以閱讀它,所以它是文本。二進制和文本數據之間的區別有點令人困惑,如果您想更加困惑,請閱讀this。正如該文章中所解釋的,您的問題的原因是編碼。

這取決於您如何將其輸出到您的頁面,但瀏覽器可能會或可能不會將某種編碼應用於其接收到的數據(Fiddler檢查可以更多地瞭解通過HTTP線路發送的內容)並顯示它或多或少具有可讀性的文字。

這並不適用於您的image變量,雖然,這包含了從readAsBinaryString()結果實際的二進制數據,在「原始二進制數據[原文]」形式。哦,鬆散的類型,誰在乎你回報。我猜/希望有一個字節數組。您現在需要將其發送到服務器。最好是文件上傳由<input type="file" />元素處理,但有時候你需要使用AJAX做些事情。你can't真的通過JavaScript做真正的文件上傳,雖然據我所知瀏覽器支持seems to be增加。

因此,您需要將POST與文件內容一起作爲發佈表單的參數之一。爲了在二進制數據中成功發生這種情況,您需要對錶單提交進行正確編碼。

首先確保請求是content-typeapplication/x-www-form-urlencoded。您可以在Fiddler中查看,或者諮詢manual。後者根本沒有提及任何編碼,你必須figure that out

現在您需要url-encode二進制數據才能發佈。此函數將輸入字節(解釋爲UTF-8)作爲可安全發佈的URL編碼字符串返回。然後服務器端,可以更換

System.Text.Encoding.GetEncoding( 「ISO-8859-1」)GetBytes會(_Context.Request [ 「圖像」])。

隨着

System.Text.Encoding.UTF8 .GetBytes(_Context.Request [ 「圖像」]);

但是,爲什麼你在該表單中的文件內容呢?如this answer所述,FileReader還包含readAsDataURL方法,該方法允許您直接使用reader.result作爲POST變量。

所以,你的代碼變成這樣:

var f = $("image").files[0]; 
var reader = new FileReader(); 
reader.readAsDataURL(f); 
var image = reader.result; 

$.ajax({ 
    url: theUrl, 
    type: 'POST', 
    data: { Image: image } 
}); 

然後服務器端,你必須將數據從基地64解碼:

byte[] imageBytes = System.Convert.FromBase64String(_Context.Request["Image"]); 

是如何運作的?

+0

+1感謝您的回答!不幸的是,我被指示通過無線base64編碼的線路發送二進制數據,因爲它產生的有效載荷。我在發送前在前端編碼圖像。然而,我覺得奇怪,但這可能是由於我對這個主題的淺薄理解,當我在服務器端獲得UTF8編碼字節時,剩下的字節數組長度爲25,當圖像大約爲40kB時。沒有編碼和使用原樣(來自我的OP),我留下了約40k的字節數組長度,這是圖像的大小,但是出現上述異常。 – Josh

+0

對不起,不是25 - 〜159k – Josh

+0

經過進一步的調查後,我明白了一點。對二進制數據進行編碼似乎是必要的,但是會過度誇大有效負載,因此會導致159kB的大小。有沒有辦法發送二進制數據原樣*沒有*編碼?請知道我們在後端有安全措施,以確保圖像的二進制數據有效。 – Josh

相關問題