FileReader.readAsBinaryString返回二进制或基于ascii的字符集

Does FileReader.readAsBinaryString return binary or an ASCII-based character set?

本文关键字:ascii 字符集 readAsBinaryString 返回 二进制 FileReader      更新时间:2023-09-26

简而言之,我想将图像的二进制数据发送给我的处理程序,该处理程序将作为字节数组保存在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(一个潜在的危险请求)。从…)中检测到表单值。我宁愿不更改requestValidationMode,因为它向XSS开放,那么如何转义二进制字符串呢?Base64编码是否涵盖了这一点,如果是,处理程序中从Base64转换是否包含有关其数据类型的元数据?

它确实有助于看到您在代码中所做的事情,这就是我要求您展示它的原因。我你的代码是这样的:

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...

我的输出是…二进制数据?

是的,但是你可以阅读它,所以它是文本。二进制数据和文本数据之间的区别有点令人困惑,如果您想了解更多,请阅读本文。正如那篇文章所解释的,问题的原因是编码。

这取决于您如何将其输出到您的页面,但是浏览器可能会或可能不会对它接收到的数据应用特定的编码(Fiddler检查可以告诉您更多关于通过HTTP线发送的内容),并将其显示为或多或少可读的文本。

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

因此,您需要将文件内容作为发布表单的参数之一POST。为了成功地处理二进制数据,您需要为表单提交对其进行适当编码。

首先确保请求是用application/x-www-form-urlencodedcontent-type发出的。您可以在Fiddler或查阅手册中检查这一点。后者根本没有提到任何编码,您必须弄清楚。

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

System.Text.Encoding.GetEncoding("iso - 8859 - 1 -").GetBytes (_Context.Request["Image");

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 }
});

然后服务器端,你必须解码64进制的数据:

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

这是如何工作的?