转换为Base64在JavaScript中无德precated“逃离”电话 [英] Converting to Base64 in JavaScript without Deprecated 'Escape' call

查看:173
本文介绍了转换为Base64在JavaScript中无德precated“逃离”电话的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的名字是费斯图斯。

我需要字符串转换为从Base64编码在通过JavaScript的浏览器。该主题将相当不错在这个网站和Mozilla和建议的解决方案似乎是沿着这些路线:

I need to convert strings to and from Base64 in a browser via JavaScript. The topic is covered quite well on this site and on Mozilla, and the suggested solution seems to be along these lines:

function toBase64(str) {
    return window.btoa(unescape(encodeURIComponent(str)));
}

function fromBase64(str) {
    return decodeURIComponent(escape(window.atob(str)));
}

我做了一些更多的研究和发现,越狱() UNESCAPE()是德precated和不应再使用。考虑到这一点,我试图消除对德precated功能,它产生的呼叫:

I did a bit more research and found out that escape() and unescape() are deprecated and should no longer be used. With that in mind, I tried removing calls to the deprecated functions which yields:

function toBase64(str) {
    return window.btoa(encodeURIComponent(str));
}

function fromBase64(str) {
    return decodeURIComponent(window.atob(str));
}

这似乎工作,但它回避以下问题:

This seems to work but it begs the following questions:

(1)为什么最初提出的解决方案,包括越狱()的调用 UNESCAPE()?该解决方案以取消precation之前有人提议,但presumably这些功能添加某种价值的时间。

(1) Why did the originally proposed solution include calls to escape() and unescape()? The solution was proposed prior to deprecation but presumably these functions added some kind of value at the time.

(2)是否有一定的优势情况下,我的去除这些德$ P $的pcated调用将导致我的包装功能失效?

(2) Are there certain edge cases where my removal of these deprecated calls will cause my wrapper functions to fail?

注:有StackOverflow上串=> Base64编码转换的问题等,更为冗长和复杂解决方案。我敢肯定,他们的工作只是罚款,但我的问题是具体涉及到这个的特别的流行的解决方案。

NOTE: There are other, far more verbose and complex solutions on StackOverflow to the problem of string=>Base64 conversion. I'm sure they work just fine but my question is specifically related to this particular popular solution.

谢谢,

非斯

推荐答案

TL; DR原则越狱() / UNESCAPE()是的没有必要的,和你没有去precated功能,第二个版本是安全的,但它产生的base64长带codeD输出:

TL;DR In principle escape()/unescape() are not necessary, and your second version without the deprecated functions is safe, yet it generates longer base64 encoded output:


  • 执行console.log(德codeURIComponent(ATOB(BTOA(EN codeURIComponent(€URO)))))

  • <$c$c>console.log(de$c$cURIComponent(escape(atob(btoa(unescape(en$c$cURIComponent(\"€uro\")))))))

  • console.log(decodeURIComponent(atob(btoa(encodeURIComponent("€uro")))))
  • console.log(decodeURIComponent(escape(atob(btoa(unescape(encodeURIComponent("€uro")))))))

两者创造的产值€URO然而,如果没有版本越狱() / UNESCAPE()具有较长的base64重新presentation

both create the output "€uro" yet the version without escape()/unescape() with a longer base64 representation


  • BTOA(EN codeURIComponent(€URO))。长度// = 16

  • BTOA(UNESCAPE(EN codeURIComponent(€URO)))//长度= 8

  • btoa(encodeURIComponent("€uro")).length // = 16
  • btoa(unescape(encodeURIComponent("€uro"))).length // = 8

越狱() / UNESCAPE()一步只能成为必要的,如果对方(例如,一个不可调整的PHP -script期待在具体的方式来完成的base64)。

The escape()/unescape() step can only become necessary if the counterpart (e.g. an unadjustable php-Script expecting the base64 to be done in the specific way.).

长版:

首先,以更好地理解 toBase64() fromBase64()两个版本的之间的差异你上面建议,让我们来看看在<$ C $ç> BTOA()这是问题的核心。文件说,这 BTOA 命名为记忆,这样

First, to better understand the differences in between the two versions of toBase64() and fromBase64() that you suggest above, let us have a look to the btoa() which is at the core of the issue. Documentation says, that the naming of btoa is mnemonic so that

B可以被认为代表二进制,和一为ASCII

"b" can be considered to stand for "binary", and the "a" for "ASCII".

这是有点误导,如文档赶忙补充一点,

which is somewhat misleading, as the documentation hastens to add, that

在实践中,虽然主要是为历史的原因,输入和这些函数的输出是单向code字符串。

in practice, though, for primarily historical reasons, both the input and output of these functions are Unicode strings.

甚至更少完善, BTOA()确实只接受

Even less perfect, btoa() is indeed only accepting

在范围内的字符U + 0000至U + 00FF

characters in the range U+0000 to U+00FF

明明白白spoking只有英文字母数字文本与BTOA作品()。

plainly spoking only only English alpha-numeric-text works with btoa().

的<一个目的href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/en$c$cURIComponent\"相对=nofollow>恩codeURIComponent(),你在这两个版本的都有,就是帮助了具有U + 0000范围之外的字符串到U + 00FF。
一个例子是字符串UU€有三个字符

The purpose of encodeURIComponent(), which you have in both of your versions, is to help out with strings having character outside the range U+0000 to U+00FF. An example would be the string "uü€" having three characters


  • A (U + 0061)

  • A (U + 00E4)

  • (U + 20AC)

  • a (U+0061)
  • ä (U+00E4)
  • (U+20AC)

下面只有两个第一字符的范围。
第三个字符,欧元符号,在外面和 window.btoa(€)引发了一系列的错误。
为了避免这种需要的解决方案设定的U + 0000至U + 00FF内重新present€的错误。这是window.en codeURIComponent做:

Here only the two first characters are in range. The third character, the Euro sign, is outside and window.btoa("€") raises an out of range error. To avoid such an error a solution is needed to represent "€" within the set of U+0000 to U+00FF. This is what window.encodeURIComponent does:

window.en codeURIComponent(UU€)结果
创建以下字符串:结果
一%C3%A4%E2%82%AC
其中某些字符已恩codeD

window.encodeURIComponent("uü€")
creates the following string:
"a%C3%A4%E2%82%AC" in which some characters have been encoded


  • A = A (保持不变)

  • A = %C3%A4 (改变其UTF8重新presentation)

  • = %E2%82%AC (改变其UTF8重新presentation)

  • a = a (stayed the same)
  • ä = %C3%A4 (changed to its utf8 representation)
  • = %E2%82%AC (changed to its utf8 representation)

的(改变其UTF8重新presentation)使用字符%,而对于人物的UTF8重新presentation的每个字节两位数的作品。在%是U + 0025,从而允许在 BTOA() -range。的结果
window.en codeURIComponent(UU€)然后可以输送到 BTOA(),因为它有没有超出范围字符了:

The (changed to its utf8 representation) works by using the character "%" and a two digit number for each byte of the character's utf8 representation. The "%" is U+0025 and hence allowed inside the btoa()-range. The result of window.encodeURIComponent("uü€") can then be fed to btoa() as it has no out of range characters anymore:

BTOA(A%C3%A4%E2%82%AC)\\\\ =YSVDMyVBNCVFMiU4MiVBQw ==

使用 UNESCAPE的症结() BTOA() EN codeURIComponent()是utf8的再presentation的所有字节使用最多3个字符%XX 来存储所有的潜力一个字节为0x00到0xFF的值。这里是 UNESCAPE() 能起到可选角色即可。这是因为 UNESCAPE()通吃例如%XX 字节,并在其位置单一的Uni code创建字符允许的U + 0000到0 + 00FF范围。

The crux of using an unescape() in between the btoa() and the encodeURIComponent() is that all bytes of the utf8 representation use up 3 characters %xx to store all potential values of a byte 0x00 to 0xFF. Here is where unescape() can play an optional role. This is because unescape() takes all such %xx bytes and creates in its place a single Unicode character in the allowed U+0000 to 0+00FF range.

要检查:


  • BTOA(EN codeURIComponent(UU€)))//长度= 24

  • BTOA(UNESCAPE(EN codeURIComponent(UU€)))//长度= 8

  • btoa(encodeURIComponent("uü€"))).length // = 24
  • btoa(unescape(encodeURIComponent("uü€"))).length // = 8

的主要区别是通过可选的越狱() / <$长度减少文字的base64再presentation的,额外分析的成本C $ C> UNESCAPE(),这主要是ASCII字符集文本的情况下是最小的反正。

the main difference is a length reduction of the base64 representation of the text, at the cost of additional parsing via the optional escape()/unescape(), which in case of mainly ASCII character set text is minimal anyway.

的主要教训明白的是, BTOA()被误导性地命名,并要求统一code U + 0000到 EN codeURIComponent()本身产生。去precated 越狱() / UNESCAPE()不仅拥有节省空间的特点,这也许是可取的但不是必须的。统一code符号的问题> U + 00FF在这里讨论的<一个href=\"https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding#The_.22Uni$c$c_Problem.22\"相对=nofollow> BTOA / ATOB统一code问题,其中甚至提到如何改善的所有UTF8统一code按钮base64编码在现代浏览器可能。

The main lesson to understand is that btoa() is misleadingly named and requires Unicode U+0000 to U+00FF characters which encodeURIComponent() by itself generates. The deprecated escape()/unescape() only has a space saving feature, which is maybe desirable but not necessary. The problem of Unicode symbols > U+00FF is addressed here as the btoa/atob Unicode problem, which mentions even ways to improve "all UTF8 Unicode" to base64 encoding possible in modern browsers.

这篇关于转换为Base64在JavaScript中无德precated“逃离”电话的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆