当前位置: 首页 > 知识库问答 >
问题:

在JavaScript中转换为Base64而不使用不推荐的“Escape”调用

牛越
2023-03-14

我叫Festus

我需要通过JavaScript在浏览器中将字符串与Base64相互转换。这个主题在这个网站和Mozilla上都有很好的介绍,建议的解决方案似乎是这样的:

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

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

我做了更多的研究,发现escape()unescape()已被弃用,不应再使用。考虑到这一点,我尝试删除对不推荐使用的函数的调用,这些函数会产生:

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

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

这似乎行得通,但它引出了以下问题:

(1) 为什么最初提出的解决方案包括对 escape() 和 unescape() 的调用?该解决方案是在弃用之前提出的,但据推测,这些函数在当时增加了某种价值。

(2)是否存在某些边缘情况,即我删除这些已弃用的调用会导致我的包装函数失败?

注意:StackOverflow上还有其他更冗长和复杂的解决字符串=问题的解决方案

谢谢

费斯图斯

共有1个答案

南宫胡媚
2023-03-14

TL;DR 原则上 escape()/unescape() 不是必需的,没有弃用函数的第二个版本是安全的,但它会生成更长的 base64 编码输出:

    < Li > < code > console . log(decodeURIComponent(atob(btoa(encodeURIComponent("·uro ")))) < Li > < code > console . log(decodeURIComponent(escape(atob(btoa(unescape(encodeURIComponent("·uro "))))))

两者都创建了输出"欧元区",但没有逃逸()/的版本具有更长的Bas64表示

  • btoa(编码URI组件(“€uro”))。长度//=16
  • btoa(unescape(encodeURI组件(“€uro”))。长度//=8

escape()/unescape()<-code>步骤只有在对应的步骤(例如,不可调整的php脚本,期望以特定方式完成base64)时才有必要。

长版本:

首先,为了更好地理解您在上面建议的toBase64()from mBase64()两个版本之间的差异,让我们看看btoa(),它是问题的核心。文档说,btoa的命名是助记符

“b”可以被认为代表“二进制”,“a”代表“ASCII”。

这有点误导,因为留档急于补充

然而,实际上,主要出于历史原因,这些函数的输入和输出都是Unicodehtml" target="_blank">字符串。

更不完美的是,< code>btoa()实际上只接受

U 0000到U 00FF范围内的字符

只讲英文字母数字文本与btoa()一起使用。

两个版本中都有encodeURIComponent(),它的目的是帮助处理字符在U 0000到U 00FF范围之外的字符串。例如,字符串“uü€”有三个字符

  • a(U 0061)
  • ä(U 00E4)
  • 欧元(U 20AC)

这里只有前两个字符在范围内。第三个字符,欧元符号,在外面,window.btoa("欧元")引发范围外错误。为了避免这样的错误,需要一个解决方案来表示U 0000到U 00FF集合中的“欧元”。这就是window.encodeURIComponent所做的:

<code>窗口。encodeURIComponent(“uü€”)
创建以下字符串:
“a䀔其中某些字符已编码

  • a=a(保持不变)
  • =(更改为其utf8表示)
  • 欧元=欧元(更改为其utf8表示)

(更改为其utf8表示形式)通过使用字符“%”和字符utf8表示形式的每个字节的两位数来工作。“%”是U 0025,因此允许在btoa()范围内。window.encodeURIComponent("uü欧元")的结果可以提供给btoa(),因为它不再有超出范围的字符:

btoa(“a䀔) \\ = “YSVDMyVBNCVFMiU4MiVBQw==”

在< code>btoa()和< code > encodeURIComponent()之间使用< code>unescape()的关键在于,utf8表示的所有字节都使用3个字符< code>%xx来存储一个字节0x00到0xFF的所有可能值。这就是< code>unescape()可以发挥可选作用的地方。这是因为< code>unescape()接受所有这样的< code>%xx字节,并在允许的U 0000到0 00FF范围内创建一个Unicode字符。

要检查:

    < Li > < code > btoa(encodeURIComponent(" uü"))。长度// = 24 < Li > < code > btoa(unescape(encodeURIComponent(" uü"))。长度// = 8

主要区别是减少了文本的Bas64表示的长度,但代价是通过可选的转义()/未转义()进行额外的解析,这在主要是ASCII字符集文本的情况下无论如何都是最小的。

需要理解的主要教训是,< code>btoa()的命名容易引起误解,并且需要由< code > encodeURIComponent()自己生成的Unicode U 0000到U 00FF字符。不推荐使用的< code > escape()/< code > unescape()只有一个节省空间的特性,这可能是可取的,但不是必需的。Unicode符号的问题

 类似资料:
  • 我收到此错误,并且尝试将更改为仍然收到不同的错误。

  • 问题内容: 我发现这段代码的工作方式是,我可以以编程方式创建richfaces下拉菜单。但是不推荐使用某些代码。谁能告诉我要放什么而不是不赞成使用的电话? 谢谢 不推荐使用的代码行是: 问题答案: javadocs明确指出: 不推荐使用 。通过调用getExpressionFactory()然后 ExpressionFactory.createMethodExpression(javax.el.E

  • 本文向大家介绍为何官方推荐使用axios而不用vue-resource?相关面试题,主要包含被问及为何官方推荐使用axios而不用vue-resource?时的应答技巧和注意事项,需要的朋友参考一下 1.vue-resources不再更新了,vue作者尤大推荐axios。 2.axios更加强大 3.axios就是一个基于ES6的Promise的网络请求库,其实说干净了就是一个打包好的XMLHtt

  • 问题内容: 我收到此警告,但是该程序仍然可以正常运行。 MySQL代码向我显示了一条PHP消息: 不推荐使用:mysql_connect():不推荐使用mysql扩展,以后将被删除:在第2行的C:\ xampp \ htdocs \ task \ media \ new \ connect.inc.php中使用mysqli或PDO代替 我的页面是 这是什么意思,我该如何消除该消息? 问题答案: 有

  • 问题内容: 我正在尝试使用和进行单元测试。 当我不包含注释时,测试将失败。但 不推荐使用MockitoJUnitRunner类型 我正在使用Mockito 2.6.9。我应该怎么做? 问题答案: 现在确实已弃用,应该改为使用。如您所见,仅软件包名称已更改,该类的简单名称仍为 。 摘录自javadoc : 移至,该课程将在Mockito 3中删除

  • 新的侦听器(又名OnCameraMoveListener())方法onCameraMove()没有CameraPosition CameraPosition输入变量,所以我很迷惑:有没有方法回收我的旧代码? 这里有一些参考资料。