admin管理员组

文章数量:1323730

I'm doing some pretty unholy things with JavaScript, and I've run into a weird problem.

I am creating binary data that fills a buffer of a static size. If the content doesn't fill the buffer, the remainder is filled with null characters.

The next step is to convert to base64.

The size (bytes) isn't always a multiple of 3, so I may need to add padding to the end. The last bytes in the buffer are always null (actually, it's about a kb of nulls).

When I convert this to base64 on Firefox and Chrome, I get an ERR_INVALID_URL when I have a trailing '=', but it downloads fine when I don't.

For example:

var url = "data:application/octet-stream;base64,";

window.open(url + "AAAA"); // works
window.open(url + "AAAA="); // doesn't work
window.open(url + "icw="); // works

My files work, but they're not up to spec.

Is there a reason why this is invalid base64? More importantly, is this a bug or part of the specification?

Edit:

I've posted an answer that gives some of the oddities between Firefox and Chrome. Does anyone know what the standard specifies? Or is it one of those loose specifications that causes fragmentation? I'd like something definitive if possible.

I'm doing some pretty unholy things with JavaScript, and I've run into a weird problem.

I am creating binary data that fills a buffer of a static size. If the content doesn't fill the buffer, the remainder is filled with null characters.

The next step is to convert to base64.

The size (bytes) isn't always a multiple of 3, so I may need to add padding to the end. The last bytes in the buffer are always null (actually, it's about a kb of nulls).

When I convert this to base64 on Firefox and Chrome, I get an ERR_INVALID_URL when I have a trailing '=', but it downloads fine when I don't.

For example:

var url = "data:application/octet-stream;base64,";

window.open(url + "AAAA"); // works
window.open(url + "AAAA="); // doesn't work
window.open(url + "icw="); // works

My files work, but they're not up to spec.

Is there a reason why this is invalid base64? More importantly, is this a bug or part of the specification?

Edit:

I've posted an answer that gives some of the oddities between Firefox and Chrome. Does anyone know what the standard specifies? Or is it one of those loose specifications that causes fragmentation? I'd like something definitive if possible.

Share Improve this question edited Jun 4, 2011 at 17:52 beatgammit asked Jun 4, 2011 at 17:09 beatgammitbeatgammit 20.2k20 gold badges90 silver badges131 bronze badges 2
  • I added another thing that works (non-null string with equals sign). – beatgammit Commented Jun 4, 2011 at 17:28
  • Wow there sure is a lot of confusing and contradictory information out there about data URLs and the encoding. – Pointy Commented Jun 4, 2011 at 17:49
Add a ment  | 

3 Answers 3

Reset to default 5

The padding character = is used to fill up to a multiple of four code characters. As every three bytes of input are mapped onto four bytes of output, a number of input bytes that is not a multiple of three requires padding (a remainder of one byte requires == and a remainder of two bytes requires =).

In you case AAAA already is a valid code word and doesn’t require padding.

Why would you imagine that adding an "=" character to the end of the string would work? That's not a valid character in base64.

The character set is upper- and lower-case letters; the digits; and "+" and "/". Anything else is therefore not valid in a base64 string.

edit — well for URLs it seems that instead of "+" and "/" you use "-" and "_" (for positions 62 and 63 in the character set).

edit some more — this is a very confusing topic due to the existence of different, apparently authoritative but contradictory, sources of information. For example, the Mozilla description of the data URL scheme makes no mention of using the "filename-friendly" alternate encoding. Same goes for the IETF data url RFC. However, other IETF documents clearly discuss and specify the variation with "-" and "_" replacing the problematic (for file names) "+" and "/".

Therefore, I declare myself ignorant :-) Gumbo is probably right, that the plaints you're getting are about incorrect padding (that is, padding when no padding is actually necessary).

Notes about different browsers:

  • Chrome
    • datalength % 4 === 1- a single equals is necessary
    • datalength % 4 === 2- two equals are necessary
  • Firefox- equals signs are optional, but follow the same conventions as in Chrome

This is the line I used to test it (I replaced AAAAAA== with a different string each time):

var url = "data:application/octet-stream;base64,AAAAAA=="; window.open(url);

Also, both Firefox and Chrome use + & /, not - and _.

Source:

My tests on Ubuntu 11.04 with Chrome 11 and Firefox 4.

Edit:

The code I need this for is a tar utility for Javascript. My code works as is, but I'd like to be as standards-pliant as possible, and I'm missing a byte I think. No biggie because tar in Linux recognizes it.

本文标签: javascriptHTML5 Data URI fails when a base64 null is followed by an Stack Overflow