admin管理员组

文章数量:1287577

In short, I want to send the binary data of the image to my handler that will get saved in the DB as a byte array. Reading the value of a file input using readAsBinaryString(f) in my Javascript, I'll get output like this:

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

That data is sent via AJAX:

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

This is a binary string? When I send this string to my handler (IHttpHandler), in order to store it into a byte array, I may only get the bytes if I set the encoding to 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"]);

    //...
}

Is this normal? This also throws an HttpRequestValidationException (A potentially dangerous Request.Form value was detected from the..). I'd rather not change the requestValidationMode since it opens up to XSS, so how does one escape the binary string? Does Base64 encoding cover this, and if so, does converting from Base64 in the handler contain metadata about its data type?

In short, I want to send the binary data of the image to my handler that will get saved in the DB as a byte array. Reading the value of a file input using readAsBinaryString(f) in my Javascript, I'll get output like this:

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

That data is sent via AJAX:

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

This is a binary string? When I send this string to my handler (IHttpHandler), in order to store it into a byte array, I may only get the bytes if I set the encoding to 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"]);

    //...
}

Is this normal? This also throws an HttpRequestValidationException (A potentially dangerous Request.Form value was detected from the..). I'd rather not change the requestValidationMode since it opens up to XSS, so how does one escape the binary string? Does Base64 encoding cover this, and if so, does converting from Base64 in the handler contain metadata about its data type?

Share Improve this question edited May 17, 2013 at 21:31 Josh asked May 17, 2013 at 15:55 JoshJosh 1,0194 gold badges17 silver badges32 bronze badges 9
  • There's another way at stackoverflow./questions/3436398/… – stuartd Commented May 17, 2013 at 15:59
  • Thanks for the response, stuartd. My issue there is my initial "binary string" isn't represented as 1s and 0s, it's as that above snippet, which obviously isn't binary, I think. Why does readAsBinaryString return that as that? Is that another form of binary I'm not familiar with? – Josh Commented May 17, 2013 at 16:01
  • That looks like Assembly to me. Which in and of itself, is odd. – Brian Commented May 17, 2013 at 16:04
  • Yes, that string is normal... If you're passing your string to a handler you should encode it to base64 and in the handler decode the data back... 1s and 0s are used in assembly... it's inefficient to pass data like that... – bastos.sergio Commented May 17, 2013 at 16:13
  • Fair enough. If I send it as base64 and decode it, and store as bytes array, will the final result include data's type? Such that when I retrieve the data in the future from DB, it will know whether it's png, gif, etc.? – Josh Commented May 17, 2013 at 16:17
 |  Show 4 more ments

1 Answer 1

Reset to default 9

It really helps to see what you are doing in code, that's why I asked you to show it. I guess your code looks like this:

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

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

Now when you say:

I'll get output like this:

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

Is my output [...] binary data?

Well yes, but you can read it, so it is text. The difference between binary and textual data is a bit confusing, read this if you want to get more confused. The cause of your problem is encoding, as explained in that article.

It depends on how you output it to your page, but the browser may or may not apply a certain encoding to the data it receives (a Fiddler inspection can teach you more on what's being sent over the HTTP wire) and display it as more or less readable text.

This does not apply to your image variable though, which contains the actual, binary data from the readAsBinaryString() result, in the form of "raw binary data[sic]". Oh, loosely-typed, who cares what you return. I guess/hope a byte array. You now need to send this to a server. Preferably, file uploads are handled by <input type="file" /> elements, but sometimes you'll need to do things using AJAX. You can't really do real file uploads through JavaScript, although as far as I know browser support seems to be increasing.

So you'll need to POST with the file contents as one of the posted form's parameters. In order for this to happen successfully with binary data, you'll need to properly encode it for form submission.

First make sure the request is made with the content-type of application/x-www-form-urlencoded. You can check this in Fiddler or by consulting the manual. The latter does not mention any encoding at all, you have to figure that out.

Now you need to url-encode the binary data in order to post it. This function returns the input bytes, interpreted as UTF-8, as an URL-encoded string that can safely be posted. Then serverside, you can replace

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

With

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

But why do you have the file's contents in that form anyway? As this answer mentions, the FileReader also contains a readAsDataURL method, which allows you to use reader.result directly as POST variable.

So, your code bees like this:

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

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

Then serverside, you will have to decode the data from base 64:

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

How does that work?

本文标签: cDoes FileReaderreadAsBinaryString return binary or an ASCIIbased character setStack Overflow