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

Jos*_*osh 5 javascript c# asp.net

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

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..  
Run Code Online (Sandbox Code Playgroud)

该数据通过AJAX发送:

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

这是二进制字符串?当我将此字符串发送到我的处理程序(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"]);

    //...
}
Run Code Online (Sandbox Code Playgroud)

这是正常的吗?这也会抛出一个HttpRequestValidationException(从..中检测到一个潜在危险的Request.Form值).我宁愿不改变,requestValidationMode因为它打开了XSS,那么如何逃避二进制字符串?Base64编码是否涵盖了这一点,如果是这样,处理程序中从Base64转换是否包含有关其数据类型的元数据?

Cod*_*ter 9

在代码中查看您正在做什么真的很有帮助,这就是我要求您展示它的原因.我你的代码看起来像这样:

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

$.ajax({
    url: theUrl,
    type: 'POST',
    data: { Image: image }
});
Run Code Online (Sandbox Code Playgroud)

现在当你说:

我会得到这样的输出:

GIF89a,úæÿÿÿ2c½3...
Run Code Online (Sandbox Code Playgroud)

我的输出二进制数据吗?

是的,但你可以阅读它,所以它是文本.二进制文本数据和文本数据之间的区别有点令人困惑,如果您想要更加困惑,请阅读此内容.问题的原因是编码,如该文章中所述.

这取决于您如何将其输出到您的页面,但浏览器可能会或可能不会对其接收的数据应用某种编码(Fiddler检查可以教您更多关于通过HTTP线路发送的内容)并将其显示为更多或不太可读的文字.

这不适用于您的image变量,它包含结果中的实际二进制数据readAsBinaryString(),格式为"原始二进制数据[sic]".哦,松散型,谁在乎你的回归.我想/希望一个字节数组.您现在需要将其发送到服务器.最好是文件上传由<input type="file" />元素处理,但有时你需要使用AJAX来处理.你不能真正通过JavaScript进行真正的文件上传,尽管据我所知,浏览器支持似乎在增加.

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

首先确保请求与制作content-typeapplication/x-www-form-urlencoded.您可以在Fiddler中查看,也可以参考手册.后者根本没有提到任何编码,你必须弄明白.

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

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

System.Text.Encoding.UTF8 .GetBytes(_Context.Request ["Image"]);

但是为什么你还有那个表格中的文件内容呢?正如这个答案所提到的,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 }
});
Run Code Online (Sandbox Code Playgroud)

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

byte[] imageBytes = System.Convert.FromBase64String(_Context.Request["Image"]);
Run Code Online (Sandbox Code Playgroud)

这是如何运作的?