FileReader.readAsBinaryString是返回二进制还是基于ASCII的字符集?

时间:2013-05-17 15:55:55

标签: c# javascript asp.net

简而言之,我想将图像的二进制数据发送到我的处理程序,该处理程序将作为字节数组保存在DB中。在我的Javascript中使用readAsBinaryString(f)读取文件输入的值,我会得到如下输出:

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转换是否包含有关其数据类型的元数据?

1 个答案:

答案 0 :(得分:8)

查看您在代码中所做的事情真的很有帮助,这就是我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()结果的实际二进制数据,格式为&#34;原始二进制数据[原文如此] &#34; 。哦,松散型,谁在乎你的回归。我想/希望一个字节数组。您现在需要将其发送到服务器。文件上传最好由<input type="file" />元素处理,但有时您需要使用AJAX进行操作。您can't确实通过JavaScript进行了真正的文件上传,但据我所知,浏览器支持seems to be正在增加。

因此,您需要POST将文件内容作为已发布表单的参数之一。为了使二进制数据成功发生,您需要对表单提交进行正确编码。

首先确保使用content-type application/x-www-form-urlencoded发出请求。您可以在Fiddler中查看,也可以咨询manual。后者根本没有提到任何编码,你必须figure that out

现在您需要url-encode二进制数据才能发布它。此函数返回输入字节(解释为UTF-8),作为可以安全发布的URL编码字符串。然后在服务器端,您可以替换

  

System.Text.Encoding.GetEncoding(&#34; ISO-8859-1&#34)。GetBytes会(_Context.Request [&#34;图像&#34;]);

  。

System.Text.Encoding.UTF8 GetBytes会(_Context.Request [&#34;图像&#34;]);

但是为什么你还有那个表格中的文件内容呢?如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 }
});

然后在服务器端,你必须解码base 64中的数据:

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

这是如何运作的?