【问题标题】:How can you encode a string to Base64 in JavaScript?如何在 JavaScript 中将字符串编码为 Base64?
【发布时间】:2010-09-19 19:04:53
【问题描述】:

我有一个 PHP 脚本,可以将 PNG 图像编码为 Base64 字符串。

我想用 JavaScript 做同样的事情。我知道如何打开文件,但我不确定如何进行编码。我不习惯使用二进制数据。

【问题讨论】:

标签: javascript base64 binaryfiles


【解决方案1】:

这里的所有解决方案在某些情况下似乎都失败了,而且理解起来相当复杂。 特别是对于非拉丁语言,例如 ARABIC

这是一个编码 UTF-16 的简短解决方案

//decodes utf-16 characters such as ARABIC, URDU,PASHTO text
function decodeBase64(s) {
    var percentEncodedStr = atob(s).split('').map(function (c) {
        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
    }).join('');
    return decodeURIComponent(percentEncodedStr);
}

【讨论】:

    【解决方案2】:

    随着 btoa() 和 atob() 被弃用,你可以用 Buffer 替换它们。按照下面的替代方案在 nodejs 和浏览器上运行。

    如果您使用的是 nodejs,只需将 atob 和 btoa 替换为 Buffer。 Here is the official documentation Buffers in nodejs:

    //With NodeJS
    
    export const encodeBase64 = (data) => {
        return Buffer.from(data).toString('base64');
    }
    export const decodeBase64 = (data) => {
        return Buffer.from(data, 'base64').toString('ascii');
    }
    

    否则,您可以使用“yarn add buffer”或“npm i buffer”安装缓冲区以在浏览器上运行。 buffer 模块的 API 与 node 的 Buffer API 相同。

    这是一个使用 javascript 模块到浏览器的 React 示例,但它可以在任何使用 webpack 或 parcel 甚至带有脚本 src 的 vanilla javascript 的现代 javascript 前端应用程序上运行:

    //this will run on browser    
    import React from "react";
    import { Buffer } from 'buffer';
    export default function App() {
    
      const encodeBase64 = (data) => {
        return Buffer.from(data).toString('base64');
      }
      const decodeBase64 = (data) => {
        return Buffer.from(data, 'base64').toString('ascii');
      }
    
      return <div>
        {'encoded test to base64 = ' + encodeBase64('test')}<br />
        {'decoded dGVzdA== to ascII = ' + decodeBase64('dGVzdA==')}
      </div>;
    }
    

    上面的反应钩子会产生:

    encoded test to base64 = dGVzdA==
    decoded dGVzdA== to ascII = test
    

    【讨论】:

      【解决方案3】:

      这个问题及其答案为我指明了正确的方向。 特别是对于 Unicode,atobbtoa 不能使用“香草”,而现在 一切 都是 Unicode...

      直接来自 Mozilla,为此提供了两个不错的功能。
      内含 Unicode 和 HTML 标签测试:

      function b64EncodeUnicode(str) {
          return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
              return String.fromCharCode('0x' + p1);
          }));
      }
      
      b64EncodeUnicode('✓ à la mode'); // "4pyTIMOgIGxhIG1vZGU="
      b64EncodeUnicode('\n'); // "Cg=="
      
      
      function b64DecodeUnicode(str) {
          return decodeURIComponent(Array.prototype.map.call(atob(str), function(c) {
              return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
          }).join(''));
      }
      
      b64DecodeUnicode('4pyTIMOgIGxhIG1vZGU='); // "✓ à la mode"
      b64DecodeUnicode('Cg=='); // "\n"
      

      与使用自定义 JavaScript 函数的原始 Base64 解码相比,这些函数的执行速度快如闪电,因为 btoaatob 在解释器之外执行。

      如果您可以忽略旧的 Internet Explorer 和旧手机(如 iPhone 3?),这应该是一个很好的解决方案。

      【讨论】:

      • 这是来自 MDN 吗?
      • 这个答案挽救了我的理智。有关其他信息 - 使用“b64EncodeUnicode()”后,您可以安全地在 PHP 中对结果字符串使用“base64_decode()”。
      【解决方案4】:

      从已接受答案下方的 cmets(由 SET 和 Stefan Steiger 编写),这里简要介绍了如何在不需要库的情况下将字符串编码/解码到 Base64/从 Base64 编码/解码。

      str = "The quick brown fox jumps over the lazy dog";
      b64 = btoa(unescape(encodeURIComponent(str)));
      str = decodeURIComponent(escape(window.atob(b64)));
      

      纯 JavaScript 演示

      const input = document.getElementsByTagName('input')[0];
      const btnConv = document.getElementById('btnConv');
      const btnDeConv = document.getElementById('btnDeConv');
      
      input.value = "The quick brown fox jumps over the lazy dog";
      
      btnConv.addEventListener('click', () => {
        const txt = input.value;
        const b64 = btoa(unescape(encodeURIComponent(txt)));
        input.value = b64;
        btnDeConv.style.display = 'block';
        btnConv.style.display = 'none';
      });
      
      btnDeConv.addEventListener('click', () => {
        var b64 = input.value;
        var txt = decodeURIComponent(escape(window.atob(b64)));
        input.value = txt;
        btnConv.style.display = 'block';
        btnDeConv.style.display = 'none';
      });
      input{width:500px;}
      #btnDeConv{display:none;}
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      
      <div><input type="text" /></div>
      <button id="btnConv">Convert</button>
      <button id="btnDeConv">DeConvert</button>

      .

      jQuery Demo (使用 jQuery 库进行显示,但不用于编码/解码)

      str = "The quick brown fox jumps over the lazy dog";
      
      $('input').val(str);
      
      $('#btnConv').click(function(){
        var txt = $('input').val();
        var b64 = btoa(unescape(encodeURIComponent(txt)));
        $('input').val(b64);
        $('#btnDeConv').show();
      });
      $('#btnDeConv').click(function(){
        var b64 = $('input').val();
        var txt = decodeURIComponent(escape(window.atob(b64)));
        $('input').val(txt);
      });
      #btnDeConv{display:none;}
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      
      <input type="text" />
      <button id="btnConv">Convert</button>
      <button id="btnDeConv">DeConvert</button>

      【讨论】:

      • 确认一下,这支持UTF-8字符吗?
      • @Crashalot 我意识到这已经晚了两年,但确实如此。当我键入此内容时,我也刚刚意识到您提供了可能使 UTF8 工作的编辑。
      • 对于在这里寻找与 Node.js 一起使用的良好解决方案的任何人,我可以确认这是可行的。对于 Node 中的解码,我使用了:Buffer.from(b64data, 'base64').toString();
      • 有人能解释一下unescapeescape 在这个解决方案中的作用吗?
      • @Sammi MDN 拥有the explanationthis 绝对是正确的方法
      【解决方案5】:

      没有btoa 中间步骤的JavaScript(没有库)

      在你写的关于字符串转换的问题标题中,但在你谈论二进制数据(图片)的问题中,所以这里有一个函数可以从 PNG 图片二进制数据开始进行适当的转换(细节和反转转换是here )。

      function bytesArrToBase64(arr) {
        const abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; // base64 alphabet
        const bin = n => n.toString(2).padStart(8,0); // convert num to 8-bit binary string
        const l = arr.length
        let result = '';
      
        for(let i=0; i<=(l-1)/3; i++) {
          let c1 = i*3+1>=l; // case when "=" is on end
          let c2 = i*3+2>=l; // case when "=" is on end
          let chunk = bin(arr[3*i]) + bin(c1? 0:arr[3*i+1]) + bin(c2? 0:arr[3*i+2]);
          let r = chunk.match(/.{1,6}/g).map((x,j)=> j==3&&c2 ? '=' :(j==2&&c1 ? '=':abc[+('0b'+x)]));
          result += r.join('');
        }
      
        return result;
      }
      
      
      
      // TEST
      
      const pic = [ // PNG binary data
          0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
          0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10,
          0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff, 0x61, 0x00, 0x00, 0x00,
          0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00,
          0x01, 0x59, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f,
          0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00,
          0x00, 0x00, 0x00, 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65,
          0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x3d, 0x22,
          0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74,
          0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d,
          0x22, 0x58, 0x4d, 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e,
          0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64,
          0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a,
          0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
          0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31,
          0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, 0x2d, 0x72, 0x64,
          0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23,
          0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64,
          0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
          0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d,
          0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
          0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, 0x69, 0x66,
          0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73,
          0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74,
          0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20,
          0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66,
          0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f,
          0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72,
          0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20,
          0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44,
          0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a,
          0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46,
          0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74,
          0x61, 0x3e, 0x0a, 0x4c, 0xc2, 0x27, 0x59, 0x00, 0x00, 0x00, 0xf9, 0x49,
          0x44, 0x41, 0x54, 0x38, 0x11, 0x95, 0x93, 0x3d, 0x0a, 0x02, 0x41, 0x0c,
          0x85, 0xb3, 0xb2, 0x85, 0xb7, 0x10, 0x6c, 0x04, 0x1b, 0x0b, 0x4b, 0x6f,
          0xe2, 0x76, 0x1e, 0xc1, 0xc2, 0x56, 0x6c, 0x2d, 0xbc, 0x85, 0xde, 0xc4,
          0xd2, 0x56, 0xb0, 0x11, 0xbc, 0x85, 0x85, 0xa0, 0xfb, 0x46, 0xbf, 0xd9,
          0x30, 0x33, 0x88, 0x06, 0x76, 0x93, 0x79, 0x93, 0xf7, 0x92, 0xf9, 0xab,
          0xcc, 0xec, 0xd9, 0x7e, 0x7f, 0xd9, 0x63, 0x33, 0x8e, 0xf9, 0x75, 0x8c,
          0x92, 0xe0, 0x34, 0xe8, 0x27, 0x88, 0xd9, 0xf4, 0x76, 0xcf, 0xb0, 0xaa,
          0x45, 0xb2, 0x0e, 0x4a, 0xe4, 0x94, 0x39, 0x59, 0x0c, 0x03, 0x54, 0x14,
          0x58, 0xce, 0xbb, 0xea, 0xdb, 0xd1, 0x3b, 0x71, 0x75, 0xb9, 0x9a, 0xe2,
          0x7a, 0x7d, 0x36, 0x3f, 0xdf, 0x4b, 0x95, 0x35, 0x09, 0x09, 0xef, 0x73,
          0xfc, 0xfa, 0x85, 0x67, 0x02, 0x3e, 0x59, 0x55, 0x31, 0x89, 0x31, 0x56,
          0x8c, 0x78, 0xb6, 0x04, 0xda, 0x23, 0x01, 0x01, 0xc8, 0x8c, 0xe5, 0x77,
          0x87, 0xbb, 0x65, 0x02, 0x24, 0xa4, 0xad, 0x82, 0xcb, 0x4b, 0x4c, 0x64,
          0x59, 0x14, 0xa0, 0x72, 0x40, 0x3f, 0xbf, 0xe6, 0x68, 0xb6, 0x9f, 0x75,
          0x08, 0x63, 0xc8, 0x9a, 0x09, 0x02, 0x25, 0x32, 0x34, 0x48, 0x7e, 0xcc,
          0x7d, 0x10, 0xaf, 0xa6, 0xd5, 0xd2, 0x1a, 0x3d, 0x89, 0x38, 0xf5, 0xf1,
          0x14, 0xb4, 0x69, 0x6a, 0x4d, 0x15, 0xf5, 0xc9, 0xf0, 0x5c, 0x1a, 0x61,
          0x8a, 0x75, 0xd1, 0xe8, 0x3a, 0x2c, 0x41, 0x5d, 0x70, 0x41, 0x20, 0x29,
          0xf9, 0x9b, 0xb1, 0x37, 0xc5, 0x4d, 0xfc, 0x45, 0x84, 0x7d, 0x08, 0x8f,
          0x89, 0x76, 0x54, 0xf1, 0x1b, 0x19, 0x92, 0xef, 0x2c, 0xbe, 0x46, 0x8e,
          0xa6, 0x49, 0x5e, 0x61, 0x89, 0xe4, 0x05, 0x5e, 0x4e, 0xa4, 0x5c, 0x10,
          0x6e, 0x9f, 0xfc, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44,
          0xae, 0x42, 0x60, 0x82
      ];
      
      let b64pic = bytesArrToBase64(pic);
      myPic.src = "data:image/png;base64,"+b64pic;
      msg.innerHTML = "Base64 encoded pic data:<br>" + b64pic;
      img { zoom: 10; image-rendering: pixelated; }
      #msg { word-break: break-all; }
      <img id="myPic">
      <code id="msg"></code>

      【讨论】:

        【解决方案6】:

        要使 Base64 编码的字符串 URL 友好,您可以在 JavaScript 中执行以下操作:

        // if this is your Base64 encoded string
        var str = 'VGhpcyBpcyBhbiBhd2Vzb21lIHNjcmlwdA=='; 
        
        // make URL friendly:
        str = str.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=+$/, '');
        
        // reverse to original encoding
        str = (str + '===').slice(0, str.length + (str.length % 4));
        str = str.replace(/-/g, '+').replace(/_/g, '/');
        

        另见这个小提琴:http://jsfiddle.net/magikMaker/7bjaT/

        【讨论】:

        • 我谦虚地建议使用encodeURIComponent 很可能会在开发人员花费更少的精力的情况下获得更好的结果。
        • encodeURIComponent 将更改 base64 编码字符串的长度,在 URL 中使用 base64 时,将“-”和“_”替换为“+”和“/”是标准做法(例如 docs.python.org/library/base64.html#base64.urlsafe_b64encode)。没必要生气。
        【解决方案7】:

        当我使用时

        btoa("☸☹☺☻☼☾☿"))
        

        我明白了:

        错误 InvalidCharacterError:要编码的字符串包含 Latin1 范围之外的字符。

        我发现文档 Unicode strings 提供了如下解决方案。

        function toBinary(string) {
          const codeUnits = new Uint16Array(string.length);
          for (let i = 0; i < codeUnits.length; i++) {
            codeUnits[i] = string.charCodeAt(i);
          }
          return String.fromCharCode(...new Uint8Array(codeUnits.buffer));
        }
        
        function fromBinary(binary) {
          const bytes = new Uint8Array(binary.length);
          for (let i = 0; i < bytes.length; i++) {
            bytes[i] = binary.charCodeAt(i);
          }
          return String.fromCharCode(...new Uint16Array(bytes.buffer));
        }
        
        const myString = "☸☹☺☻☼☾☿"
        // console.log(btoa(myString)) // Error InvalidCharacterError: The string to be encoded contains characters outside of the Latin1 range.
        const converted = toBinary(myString)
        const encoded = btoa(converted)
        console.log(encoded)
        
        const decoded = atob(encoded)
        const original = fromBinary(decoded)
        console.log(original);

        【讨论】:

        • 我只是复制粘贴来帮助不想点击链接的人...
        【解决方案8】:

        使用 js-base64 库作为

        btoa() 不适用于表情符号

        var str = "I was funny ?";
        console.log("Original string:", str);
        
        var encodedStr = Base64.encode(str)
        console.log("Encoded string:", encodedStr);
        
        var decodedStr = Base64.decode(encodedStr)
        console.log("Decoded string:", decodedStr);
        &lt;script src="https://cdn.jsdelivr.net/npm/js-base64@2.5.2/base64.min.js"&gt;&lt;/script&gt;

        【讨论】:

          【解决方案9】:

          这里是atob()btoa() JavaScript 内置函数中的LIVE DEMO

          <!DOCTYPE html>
          <html>
            <head>
              <style>
                textarea{
                  width:30%;
                  height:100px;
                }
              </style>
              <script>
                // encode string to base64
                function encode()
                {
                  var txt = document.getElementById("txt1").value;
                  var result = btoa(txt);
                  document.getElementById("txt2").value = result;
                }
                // decode base64 back to original string
                function decode()
                {
                  var txt = document.getElementById("txt3").value;
                  var result = atob(txt);
                  document.getElementById("txt4").value = result;
                }
              </script>
            </head>
            <body>
              <div>
                <textarea id="txt1">Some text to decode
                </textarea>
              </div>
              <div>
                <input type="button" id="btnencode" value="Encode" onClick="encode()"/>
              </div>
              <div>
                <textarea id="txt2">
                </textarea>
              </div>
              <br/>
              <div>
                <textarea id="txt3">U29tZSB0ZXh0IHRvIGRlY29kZQ==
                </textarea>
              </div>
              <div>
                <input type="button" id="btndecode" value="Decode" onClick="decode()"/>
              </div>
              <div>
                <textarea id="txt4">
                </textarea>
              </div>
            </body>
          </html>
          

          【讨论】:

            【解决方案10】:

            您可以使用window.btoawindow.atob...

            const encoded = window.btoa('Alireza Dezfoolian'); // encode a string
            const decoded = window.atob(encoded); // decode the string
            

            可能使用 MDN 的方式可以让您的工作做得最好...也接受 Unicode...使用这两个简单的功能:

            // UCS-2 string to Base64 encoded ASCII
            function utoa(str) {
                return window.btoa(unescape(encodeURIComponent(str)));
            }
            // Base64 encoded ASCII to UCS-2 string
            function atou(str) {
                return decodeURIComponent(escape(window.atob(str)));
            }
            // Usage:
            utoa('✓ à la mode'); // 4pyTIMOgIGxhIG1vZGU=
            atou('4pyTIMOgIGxhIG1vZGU='); // "✓ à la mode"
            
            utoa('I \u2661 Unicode!'); // SSDimaEgVW5pY29kZSE=
            atou('SSDimaEgVW5pY29kZSE='); // "I ♡ Unicode!"
            

            【讨论】:

            【解决方案11】:

            虽然需要做更多工作,但如果您想要一个高性能的原生解决方案,您可以使用一些 HTML5 函数。

            如果您可以将数据放入Blob,那么您可以使用FileReader.readAsDataURL() 函数来获得data:// URL 并切掉它的前面以获得Base64 数据。

            您可能需要做进一步的处理才能对数据进行 urldecode,因为我不确定data:// URL 是否对+ 字符进行了转义,但这应该很简单。

            【讨论】:

              【解决方案12】:

              这是window.atob + window.btoa 的缩小 polyfill:

              (function(){function t(t){this.message=t}var e="undefined"!=typeof exports?exports:this,r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";t.prototype=Error(),t.prototype.name="InvalidCharacterError",e.btoa||(e.btoa=function(e){for(var o,n,a=0,i=r,c="";e.charAt(0|a)||(i="=",a%1);c+=i.charAt(63&o>>8-8*(a%1))){if(n=e.charCodeAt(a+=.75),n>255)throw new t("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.");o=o<<8|n}return c}),e.atob||(e.atob=function(e){if(e=e.replace(/=+$/,""),1==e.length%4)throw new t("'atob' failed: The string to be decoded is not correctly encoded.");for(var o,n,a=0,i=0,c="";n=e.charAt(i++);~n&&(o=a%4?64*o+n:n,a++%4)?c+=String.fromCharCode(255&o>>(6&-2*a)):0)n=r.indexOf(n);return c})})();
              
              (function (root, factory) {
                  if (typeof define === 'function' && define.amd) {
                      // AMD. Register as an anonymous module.
                      define([], function() {factory(root);});
                  } else factory(root);
              // node.js has always supported base64 conversions, while browsers that support
              // web workers support base64 too, but you may never know.
              })(typeof exports !== "undefined" ? exports : this, function(root) {
                  if (root.atob) {
                      // Some browsers' implementation of atob doesn't support whitespaces
                      // in the encoded string (notably, IE). This wraps the native atob
                      // in a function that strips the whitespaces.
                      // The original function can be retrieved in atob.original
                      try {
                          root.atob(" ");
                      } catch(e) {
                          root.atob = (function(atob) {
                              var func = function(string) {
                                  return atob(String(string).replace(/[\t\n\f\r ]+/g, ""));
                              };
                              func.original = atob;
                              return func;
                          })(root.atob);
                      }
                      return;
                  }
              
                      // base64 character set, plus padding character (=)
                  var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
                      // Regular expression to check formal correctness of base64 encoded strings
                      b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/;
              
                  root.btoa = function(string) {
                      string = String(string);
                      var bitmap, a, b, c,
                          result = "", i = 0,
                          rest = string.length % 3; // To determine the final padding
              
                      for (; i < string.length;) {
                          if ((a = string.charCodeAt(i++)) > 255
                                  || (b = string.charCodeAt(i++)) > 255
                                  || (c = string.charCodeAt(i++)) > 255)
                              throw new TypeError("Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.");
              
                          bitmap = (a << 16) | (b << 8) | c;
                          result += b64.charAt(bitmap >> 18 & 63) + b64.charAt(bitmap >> 12 & 63)
                                  + b64.charAt(bitmap >> 6 & 63) + b64.charAt(bitmap & 63);
                      }
              
                      // If there's need of padding, replace the last 'A's with equal signs
                      return rest ? result.slice(0, rest - 3) + "===".substring(rest) : result;
                  };
              
                  root.atob = function(string) {
                      // atob can work with strings with whitespaces, even inside the encoded part,
                      // but only \t, \n, \f, \r and ' ', which can be stripped.
                      string = String(string).replace(/[\t\n\f\r ]+/g, "");
                      if (!b64re.test(string))
                          throw new TypeError("Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.");
              
                      // Adding the padding if missing, for semplicity
                      string += "==".slice(2 - (string.length & 3));
                      var bitmap, result = "", r1, r2, i = 0;
                      for (; i < string.length;) {
                          bitmap = b64.indexOf(string.charAt(i++)) << 18 | b64.indexOf(string.charAt(i++)) << 12
                                  | (r1 = b64.indexOf(string.charAt(i++))) << 6 | (r2 = b64.indexOf(string.charAt(i++)));
              
                          result += r1 === 64 ? String.fromCharCode(bitmap >> 16 & 255)
                                  : r2 === 64 ? String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255)
                                  : String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255, bitmap & 255);
                      }
                      return result;
                  };
              });
              

              来自https://github.com/MaxArt2501/base64-js/blob/master/base64.js的完整版

              【讨论】:

              • 或许也提供一个正常格式的版本?
              【解决方案13】:

              Internet Explorer 10+

              // Define the string
              var string = 'Hello World!';
              
              // Encode the String
              var encodedString = btoa(string);
              console.log(encodedString); // Outputs: "SGVsbG8gV29ybGQh"
              
              // Decode the String
              var decodedString = atob(encodedString);
              console.log(decodedString); // Outputs: "Hello World!"
              

              跨浏览器

              // Create Base64 Object
              var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(e){var t="";var n,r,i,s,o,u,a;var f=0;e=Base64._utf8_encode(e);while(f<e.length){n=e.charCodeAt(f++);r=e.charCodeAt(f++);i=e.charCodeAt(f++);s=n>>2;o=(n&3)<<4|r>>4;u=(r&15)<<2|i>>6;a=i&63;if(isNaN(r)){u=a=64}else if(isNaN(i)){a=64}t=t+this._keyStr.charAt(s)+this._keyStr.charAt(o)+this._keyStr.charAt(u)+this._keyStr.charAt(a)}return t},decode:function(e){var t="";var n,r,i;var s,o,u,a;var f=0;e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(f<e.length){s=this._keyStr.indexOf(e.charAt(f++));o=this._keyStr.indexOf(e.charAt(f++));u=this._keyStr.indexOf(e.charAt(f++));a=this._keyStr.indexOf(e.charAt(f++));n=s<<2|o>>4;r=(o&15)<<4|u>>2;i=(u&3)<<6|a;t=t+String.fromCharCode(n);if(u!=64){t=t+String.fromCharCode(r)}if(a!=64){t=t+String.fromCharCode(i)}}t=Base64._utf8_decode(t);return t},_utf8_encode:function(e){e=e.replace(/\r\n/g,"\n");var t="";for(var n=0;n<e.length;n++){var r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r)}else if(r>127&&r<2048){t+=String.fromCharCode(r>>6|192);t+=String.fromCharCode(r&63|128)}else{t+=String.fromCharCode(r>>12|224);t+=String.fromCharCode(r>>6&63|128);t+=String.fromCharCode(r&63|128)}}return t},_utf8_decode:function(e){var t="";var n=0;var r=c1=c2=0;while(n<e.length){r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r);n++}else if(r>191&&r<224){c2=e.charCodeAt(n+1);t+=String.fromCharCode((r&31)<<6|c2&63);n+=2}else{c2=e.charCodeAt(n+1);c3=e.charCodeAt(n+2);t+=String.fromCharCode((r&15)<<12|(c2&63)<<6|c3&63);n+=3}}return t}}
              
              // Define the string
              var string = 'Hello World!';
              
              // Encode the String
              var encodedString = Base64.encode(string);
              console.log(encodedString); // Outputs: "SGVsbG8gV29ybGQh"
              
              // Decode the String
              var decodedString = Base64.decode(encodedString);
              console.log(decodedString); // Outputs: "Hello World!"
              

              jsFiddle


              使用 Node.js

              这是在 Node.js 中将普通文本编码为 base64 的方法:

              //Buffer() requires a number, array or string as the first parameter, and an optional encoding type as the second parameter.
              // The default is "utf8". Possible encoding types are "ascii", "utf8", "ucs2", "base64", "binary", and "hex"
              var b = new Buffer('JavaScript');
              // If we don't use toString(), JavaScript assumes we want to convert the object to utf8.
              // We can make it convert to other formats by passing the encoding type to toString().
              var s = b.toString('base64');
              

              下面是你如何解码 base64 编码的字符串:

              var b = new Buffer('SmF2YVNjcmlwdA==', 'base64')
              var s = b.toString();
              

              使用 Dojo.js

              使用 dojox.encoding.base64 对字节数组进行编码:

              var str = dojox.encoding.base64.encode(myByteArray);
              

              解码 Base64 编码的字符串:

              var bytes = dojox.encoding.base64.decode(str)
              

              Bower 安装 angular-base64

              <script src="bower_components/angular-base64/angular-base64.js"></script>
              
              angular
                  .module('myApp', ['base64'])
                  .controller('myController', [
              
                  '$base64', '$scope',
                  function($base64, $scope) {
              
                      $scope.encoded = $base64.encode('a string');
                      $scope.decoded = $base64.decode('YSBzdHJpbmc=');
              }]);
              

              【讨论】:

              • 此答案基于原始代码,不包括对此处其他答案中发布的代码的更新。
              • 建议的 NodeJS 解决方案已弃用。
              • new Buffer() 已弃用,请改用Buffer.from()
              【解决方案14】:

              我的一个项目需要将 UTF-8 字符串编码为 Base64。在转换为 UTF-8 时,这里的大多数答案似乎都无法正确处理 UTF-16 代理对,因此,为了完整起见,我将发布我的解决方案:

              function strToUTF8Base64(str) {
              
                  function decodeSurrogatePair(hi, lo) {
                      var resultChar = 0x010000;
                      resultChar += lo - 0xDC00;
                      resultChar += (hi - 0xD800) << 10;
                      return resultChar;
                  }
              
                  var bytes = [0, 0, 0];
                  var byteIndex = 0;
                  var result = [];
              
                  function output(s) {
                      result.push(s);
                  }
              
                  function emitBase64() {
              
                      var digits =
                              'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
                              'abcdefghijklmnopqrstuvwxyz' +
                              '0123456789+/';
              
                      function toDigit(value) {
                          return digits[value];
                      }
              
                      // --Byte 0--    --Byte 1--    --Byte 2--
                      // 1111  1122    2222  3333    3344  4444
              
                      var d1 = toDigit(bytes[0] >> 2);
                      var d2 = toDigit(
                          ((bytes[0] & 0x03) << 4) |
                          (bytes[1] >> 4));
                      var d3 = toDigit(
                          ((bytes[1] & 0x0F) << 2) |
                          (bytes[2] >> 6));
                      var d4 = toDigit(
                          bytes[2] & 0x3F);
              
                      if (byteIndex === 1) {
                          output(d1 + d2 + '==');
                      }
                      else if (byteIndex === 2) {
                          output(d1 + d2 + d3 + '=');
                      }
                      else {
                          output(d1 + d2 + d3 + d4);
                      }
                  }
              
                  function emit(chr) {
                      bytes[byteIndex++] = chr;
                      if (byteIndex == 3) {
                          emitBase64();
                          bytes[0] = 0;
                          bytes[1] = 0;
                          bytes[2] = 0;
                          byteIndex = 0;
                      }
                  }
              
                  function emitLast() {
                      if (byteIndex > 0) {
                          emitBase64();
                      }
                  }
              
                  // Converts the string to UTF8:
              
                  var i, chr;
                  var hi, lo;
                  for (i = 0; i < str.length; i++) {
                      chr = str.charCodeAt(i);
              
                      // Test and decode surrogate pairs in the string
                      if (chr >= 0xD800 && chr <= 0xDBFF) {
                          hi = chr;
                          lo = str.charCodeAt(i + 1);
                          if (lo >= 0xDC00 && lo <= 0xDFFF) {
                              chr = decodeSurrogatePair(hi, lo);
                              i++;
                          }
                      }
              
                      // Encode the character as UTF-8.
                      if (chr < 0x80) {
                          emit(chr);
                      }
                      else if (chr < 0x0800) {
                          emit((chr >> 6) | 0xC0);
                          emit(((chr >> 0) & 0x3F) | 0x80);
                      }
                      else if (chr < 0x10000) {
                          emit((chr >> 12) | 0xE0);
                          emit(((chr >>  6) & 0x3F) | 0x80);
                          emit(((chr >>  0) & 0x3F) | 0x80);
                      }
                      else if (chr < 0x110000) {
                          emit((chr >> 18) | 0xF0);
                          emit(((chr >> 12) & 0x3F) | 0x80);
                          emit(((chr >>  6) & 0x3F) | 0x80);
                          emit(((chr >>  0) & 0x3F) | 0x80);
                      }
                  }
              
                  emitLast();
              
                  return result.join('');
              }
              

              请注意,代码未经彻底测试。我测试了一些输入,包括 strToUTF8Base64('衠衢蠩蠨') 之类的内容,并与在线编码工具 (https://www.base64encode.org/) 的输出进行了比较。

              【讨论】:

              • 这是一项很棒的工作!但是在函数 emitBase64() 中应该是“return digits.substr(value,1)”,而不是“return digits[value]”。因为错误/偶然发现表情符号和多字节字符。但它通常会编码在线解码器无法解码的内容!这段代码毫无问题地带出了基本的西里尔字母。
              【解决方案15】:

              我宁愿使用来自CryptoJS 的 Base64 编码/解码方法,这是最流行的库,用于使用最佳实践和模式在 JavaScript 中实现的标准和安全加密算法。

              【讨论】:

                【解决方案16】:

                好吧,如果您使用的是 Dojo。它为我们提供了直接编码或解码为 Base64 的方法。

                试试这个:

                使用 dojox.encoding.base64 对字节数组进行编码:

                var str = dojox.encoding.base64.encode(myByteArray);
                

                解码 Base64 编码的字符串:

                var bytes = dojox.encoding.base64.decode(str);
                

                【讨论】:

                  【解决方案17】:

                  我已经手动将这些编码和解码方法(十六进制除外)重写为模块化格式,以实现跨平台/浏览器兼容性以及真正的私有范围,并使用btoaatob(如果存在)由于速度而不是使用自己的编码:

                  https://gist.github.com/Nijikokun/5192472

                  用法:

                  base64.encode(/* String */);
                  base64.decode(/* String */);
                  
                  utf8.encode(/* String */);
                  utf8.decode(/* String */);
                  

                  【讨论】:

                    【解决方案18】:

                    请注意,这不适用于原始 Unicode 字符串!请参阅 Unicode 部分 here

                    编码语法

                    var encodedData = window.btoa(stringToEncode);

                    解码语法

                    var decodedData = window.atob(encodedData);

                    【讨论】:

                    【解决方案19】:

                    如果需要对 HTML 图像对象进行编码,可以编写一个简单的函数,如:

                    function getBase64Image(img) {
                      var canvas = document.createElement("canvas");
                      canvas.width = img.width;
                      canvas.height = img.height;
                      var ctx = canvas.getContext("2d");
                      ctx.drawImage(img, 0, 0);
                      var dataURL = canvas.toDataURL("image/png");
                      // escape data:image prefix
                      return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
                      // or just return dataURL
                      // return dataURL
                    }
                    

                    通过id获取图片的Base64编码:

                    function getBase64ImageById(id){
                      return getBase64Image(document.getElementById(id));
                    }
                    

                    更多的是here

                    【讨论】:

                    • 是的,var img = new Image(); img.src = "../images/myPic.png";
                    【解决方案20】:

                    基本上我刚刚清理了the original code 一点点,所以JSLint 并没有那么多抱怨,而且我在 cmets 中将标记为私有的方法设为私有。我还添加了我自己项目中需要的两个方法,分别是decodeToHexencodeFromHex

                    代码:

                    var Base64 = (function() {
                        "use strict";
                    
                        var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
                    
                        var _utf8_encode = function (string) {
                    
                            var utftext = "", c, n;
                    
                            string = string.replace(/\r\n/g,"\n");
                    
                            for (n = 0; n < string.length; n++) {
                    
                                c = string.charCodeAt(n);
                    
                                if (c < 128) {
                    
                                    utftext += String.fromCharCode(c);
                    
                                } else if((c > 127) && (c < 2048)) {
                    
                                    utftext += String.fromCharCode((c >> 6) | 192);
                                    utftext += String.fromCharCode((c & 63) | 128);
                                } else {
                    
                                    utftext += String.fromCharCode((c >> 12) | 224);
                                    utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                                    utftext += String.fromCharCode((c & 63) | 128);
                                }
                            }
                            return utftext;
                        };
                    
                        var _utf8_decode = function (utftext) {
                            var string = "", i = 0, c = 0, c1 = 0, c2 = 0;
                    
                            while ( i < utftext.length ) {
                    
                                c = utftext.charCodeAt(i);
                    
                                if (c < 128) {
                    
                                    string += String.fromCharCode(c);
                                    i++;
                    
                                } else if((c > 191) && (c < 224)) {
                    
                                    c1 = utftext.charCodeAt(i+1);
                                    string += String.fromCharCode(((c & 31) << 6) | (c1 & 63));
                                    i += 2;
                    
                                } else {
                    
                                    c1 = utftext.charCodeAt(i+1);
                                    c2 = utftext.charCodeAt(i+2);
                                    string += String.fromCharCode(((c & 15) << 12) | ((c1 & 63) << 6) | (c2 & 63));
                                    i += 3;
                                }
                            }
                            return string;
                        };
                    
                        var _hexEncode = function(input) {
                            var output = '', i;
                    
                            for(i = 0; i < input.length; i++) {
                                output += input.charCodeAt(i).toString(16);
                            }
                    
                            return output;
                        };
                    
                        var _hexDecode = function(input) {
                            var output = '', i;
                    
                            if(input.length % 2 > 0) {
                                input = '0' + input;
                            }
                    
                            for(i = 0; i < input.length; i = i + 2) {
                                output += String.fromCharCode(parseInt(input.charAt(i) + input.charAt(i + 1), 16));
                            }
                            return output;
                        };
                    
                        var encode = function (input) {
                            var output = "", chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0;
                    
                            input = _utf8_encode(input);
                    
                            while (i < input.length) {
                    
                                chr1 = input.charCodeAt(i++);
                                chr2 = input.charCodeAt(i++);
                                chr3 = input.charCodeAt(i++);
                    
                                enc1 = chr1 >> 2;
                                enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
                                enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
                                enc4 = chr3 & 63;
                    
                                if (isNaN(chr2)) {
                                    enc3 = enc4 = 64;
                                } else if (isNaN(chr3)) {
                                    enc4 = 64;
                                }
                    
                                output += _keyStr.charAt(enc1);
                                output += _keyStr.charAt(enc2);
                                output += _keyStr.charAt(enc3);
                                output += _keyStr.charAt(enc4);
                            }
                            return output;
                        };
                    
                        var decode = function (input) {
                            var output = "", chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0;
                    
                            input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
                    
                            while (i < input.length) {
                    
                                enc1 = _keyStr.indexOf(input.charAt(i++));
                                enc2 = _keyStr.indexOf(input.charAt(i++));
                                enc3 = _keyStr.indexOf(input.charAt(i++));
                                enc4 = _keyStr.indexOf(input.charAt(i++));
                    
                                chr1 = (enc1 << 2) | (enc2 >> 4);
                                chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
                                chr3 = ((enc3 & 3) << 6) | enc4;
                    
                                output += String.fromCharCode(chr1);
                    
                                if (enc3 !== 64) {
                                    output += String.fromCharCode(chr2);
                                }
                                if (enc4 !== 64) {
                                    output += String.fromCharCode(chr3);
                                }
                    
                            }
                    
                            return _utf8_decode(output);
                        };
                    
                        var decodeToHex = function(input) {
                            return _hexEncode(decode(input));
                        };
                    
                        var encodeFromHex = function(input) {
                            return encode(_hexDecode(input));
                        };
                    
                        return {
                            'encode': encode,
                            'decode': decode,
                            'decodeToHex': decodeToHex,
                            'encodeFromHex': encodeFromHex
                        };
                    }());
                    

                    【讨论】:

                    • 我最初认为您将输出串联展开到单独的语句中会更优化,但在我考虑了几秒钟之后,这 应该 效率更低,因为 Javascript 字符串是不可变的,并且在处理大型二进制数据文件时会导致 4 个潜在的巨大数据 blob 副本。首先将 4 个字符连接在一起然后构建一个新字符串是一个更安全的选择。我希望我肯定知道一种更好的字符串构建方法,它肯定会在所有平台上都有效。 (甚至IE6)
                    • 我在清理最初发布的代码时没有考虑性能。我只是使它更具可读性,并通过使用显示模块模式使原始 cmets 中标记为私有的方法实际上是私有的。我相信它也可以在性能方面进行优化。不太确定垃圾收集何时开始,通过 Javascript 散列大文件并不常见(或者在任何情况下都可能不是最佳解决方案)。
                    • 有趣的是,这段代码是如何生活在这里的。此页面上已经有 3 个不同的版本。
                    【解决方案21】:

                    您可以使用btoa(到Base64)和atob(从Base64)。

                    对于 Internet Explorer 9 及更低版本,请尝试使用 jquery-base64 插件:

                    $.base64.encode("this is a test");
                    $.base64.decode("dGhpcyBpcyBhIHRlc3Q=");
                    

                    【讨论】:

                    • 为什么所有东西都需要一个 jQuery 插件 :c 这只是核心 JavaScript 功能,与 DOM 或 jQuery 无关
                    • 这不是核心功能,否则不会有那么多不同的高票答案(包括自己动手做的 tl;dr 代码)。所以,恕我直言,这实际上是 jQuery 的一个很好的用例(一个衬里,即使在 Android 的 WebView 中也可以工作)——如果它已经是一个依赖项,则更是如此。
                    • 我喜欢将这样的代码 sn-ps 安装到 jQuery 中,主要是因为它们将存在于受控命名空间中。如果您不使用 AMD 或 CommonJS 或类似的设计模式,那么您的全局命名空间很容易被一堆随机函数弄得一团糟。
                    • @Risadinha - 除了它的功能根本不依赖或扩展任何 jQuery ......从字面上看,它的代码中对 jQuery 的唯一引用是将它附加到 jQuery 对象......所以重点是什么将它附加到 jQuery 并因此需要使用 jQuery?只需让它成为自己的 1 个衬垫 base64.encode(...)base64.decode(...) ...当 jQuery 特定功能为零时将其附加到 jQuery 绝对没有意义...
                    • 没有请求 jQuery。不是一个普通的旧 JS 问题的有效答案。
                    【解决方案22】:

                    _utf8_decode 的两种实现都存在一些错误。 c1c2 被分配为全局变量,因为 var 语句的使用被破坏,而 c3 根本没有被初始化或声明。

                    它有效,但这些变量将覆盖此函数之外的任何现有同名变量。

                    这是一个不会这样做的版本:

                    // private method for UTF-8 decoding
                    _utf8_decode : function (utftext) {
                        var string = "";
                        var i = 0;
                        var c = 0, c1 = 0, c2 = 0;
                    
                        while ( i < utftext.length ) {
                    
                            c = utftext.charCodeAt(i);
                    
                            if (c < 128) {
                                string += String.fromCharCode(c);
                                i++;
                            }
                            else if((c > 191) && (c < 224)) {
                                c1 = utftext.charCodeAt(i+1);
                                string += String.fromCharCode(((c & 31) << 6) | (c1 & 63));
                                i += 2;
                            }
                            else {
                                c1 = utftext.charCodeAt(i+1);
                                c2 = utftext.charCodeAt(i+2);
                                string += String.fromCharCode(((c & 15) << 12) | ((c1 & 63) << 6) | (c2 & 63));
                                i += 3;
                            }
                        }
                        return string;
                    }
                    

                    【讨论】:

                    • @Daan 当我在 2011 年写这个答案时,我没有足够的代表来编辑答案。
                    • IE7 ?我想我们应该停止为此浪费时间编写代码,除非我们开发人员强迫他们这样做,否则人们不会停止使用这种旧技术!
                    • @RonanDejhero 它在 IE7 中不起作用吗?我不记得我是否在那个特定的浏览器中测试过。
                    • 我的意思是,如果它在 IE7 中不起作用,没有人应该关心!。我没有测试也不会测试它:)
                    【解决方案23】:

                    Sunny's code 很棒,只是它在 Internet Explorer 7 中因引用“this”而中断。通过将此类引用替换为“Base64”来修复它:

                    var Base64 = {
                        // private property
                        _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
                    
                        // public method for encoding
                        encode : function (input) {
                            var output = "";
                            var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
                            var i = 0;
                    
                            input = Base64._utf8_encode(input);
                    
                            while (i < input.length) {
                    
                                chr1 = input.charCodeAt(i++);
                                chr2 = input.charCodeAt(i++);
                                chr3 = input.charCodeAt(i++);
                    
                                enc1 = chr1 >> 2;
                                enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
                                enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
                                enc4 = chr3 & 63;
                    
                                if (isNaN(chr2)) {
                                    enc3 = enc4 = 64;
                                } else if (isNaN(chr3)) {
                                    enc4 = 64;
                                }
                    
                                output = output +
                                Base64._keyStr.charAt(enc1) + Base64._keyStr.charAt(enc2) +
                                Base64._keyStr.charAt(enc3) + Base64._keyStr.charAt(enc4);
                            }
                    
                            return output;
                        },
                    
                        // public method for decoding
                        decode : function (input) {
                            var output = "";
                            var chr1, chr2, chr3;
                            var enc1, enc2, enc3, enc4;
                            var i = 0;
                    
                            input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
                    
                            while (i < input.length) {
                    
                                enc1 = Base64._keyStr.indexOf(input.charAt(i++));
                                enc2 = Base64._keyStr.indexOf(input.charAt(i++));
                                enc3 = Base64._keyStr.indexOf(input.charAt(i++));
                                enc4 = Base64._keyStr.indexOf(input.charAt(i++));
                    
                                chr1 = (enc1 << 2) | (enc2 >> 4);
                                chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
                                chr3 = ((enc3 & 3) << 6) | enc4;
                    
                                output = output + String.fromCharCode(chr1);
                    
                                if (enc3 != 64) {
                                    output = output + String.fromCharCode(chr2);
                                }
                                if (enc4 != 64) {
                                    output = output + String.fromCharCode(chr3);
                                }
                            }
                    
                            output = Base64._utf8_decode(output);
                    
                            return output;
                        },
                    
                        // private method for UTF-8 encoding
                        _utf8_encode : function (string) {
                            string = string.replace(/\r\n/g,"\n");
                            var utftext = "";
                    
                            for (var n = 0; n < string.length; n++) {
                    
                                var c = string.charCodeAt(n);
                    
                                if (c < 128) {
                                    utftext += String.fromCharCode(c);
                                }
                                else if((c > 127) && (c < 2048)) {
                                    utftext += String.fromCharCode((c >> 6) | 192);
                                    utftext += String.fromCharCode((c & 63) | 128);
                                }
                                else {
                                    utftext += String.fromCharCode((c >> 12) | 224);
                                    utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                                    utftext += String.fromCharCode((c & 63) | 128);
                                }
                            }
                            return utftext;
                        },
                    
                        // private method for UTF-8 decoding
                        _utf8_decode : function (utftext) {
                            var string = "";
                            var i = 0;
                            var c = c1 = c2 = 0;
                    
                            while ( i < utftext.length ) {
                    
                                c = utftext.charCodeAt(i);
                    
                                if (c < 128) {
                                    string += String.fromCharCode(c);
                                    i++;
                                }
                                else if((c > 191) && (c < 224)) {
                                    c2 = utftext.charCodeAt(i+1);
                                    string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                                    i += 2;
                                }
                                else {
                                    c2 = utftext.charCodeAt(i+1);
                                    c3 = utftext.charCodeAt(i+2);
                                    string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                                    i += 3;
                                }
                            }
                            return string;
                        }
                    }
                    

                    【讨论】:

                    • 哦,我的错,我从浏览器 URL 获取输入;在哪里 |转换为 %7C;因此编码也错误。
                    • 我知道这真的很老了,但是我看到这个函数用在不止一个地方,关键字符串实际上是65个字符,而不是64个。字符串不是标准规范,我不是确定这很重要,但只是想知道它是否重要?
                    • "使用严格";是什么破坏了“this”和其他类型元素,如“with”,从我读过的内容来看,“eval”受到了抨击。所有关于滥用的错误想法。就我个人而言,我不明白为什么 JavaScript 需要沿着它前进的路线走下去,它从来都不是一个紧密绑定的程序,并且变得比现在更复杂。如果你想被绑定,那就为 javascript 做一个编译器。
                    • 我尝试使用此函数并收到错误消息: 原因:org.mozilla.javascript.EcmaError: TypeError: Cannot find function replace in object teste teste teste 我正在尝试编码 .txt用“teste teste teste”。有谁知道为什么会出现这个错误?
                    • @JonathanWagner - 有 64 个字符用于正常编码。第 65 个字符用作填充它们输入字符串没有可被 3 整除的字符数。
                    【解决方案24】:

                    From here:

                    /**
                    *
                    *  Base64 encode / decode
                    *  http://www.webtoolkit.info/
                    *
                    **/
                    var Base64 = {
                    
                        // private property
                        _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
                    
                        // public method for encoding
                        encode : function (input) {
                            var output = "";
                            var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
                            var i = 0;
                    
                            input = Base64._utf8_encode(input);
                    
                            while (i < input.length) {
                    
                                chr1 = input.charCodeAt(i++);
                                chr2 = input.charCodeAt(i++);
                                chr3 = input.charCodeAt(i++);
                    
                                enc1 = chr1 >> 2;
                                enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
                                enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
                                enc4 = chr3 & 63;
                    
                                if (isNaN(chr2)) {
                                    enc3 = enc4 = 64;
                                } else if (isNaN(chr3)) {
                                    enc4 = 64;
                                }
                    
                                output = output +
                                this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
                                this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
                            }
                            return output;
                        },
                    
                        // public method for decoding
                        decode : function (input) {
                            var output = "";
                            var chr1, chr2, chr3;
                            var enc1, enc2, enc3, enc4;
                            var i = 0;
                    
                            input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
                    
                            while (i < input.length) {
                    
                                enc1 = this._keyStr.indexOf(input.charAt(i++));
                                enc2 = this._keyStr.indexOf(input.charAt(i++));
                                enc3 = this._keyStr.indexOf(input.charAt(i++));
                                enc4 = this._keyStr.indexOf(input.charAt(i++));
                    
                                chr1 = (enc1 << 2) | (enc2 >> 4);
                                chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
                                chr3 = ((enc3 & 3) << 6) | enc4;
                    
                                output = output + String.fromCharCode(chr1);
                    
                                if (enc3 != 64) {
                                    output = output + String.fromCharCode(chr2);
                                }
                                if (enc4 != 64) {
                                    output = output + String.fromCharCode(chr3);
                                }
                            }
                    
                            output = Base64._utf8_decode(output);
                    
                            return output;
                        },
                    
                        // private method for UTF-8 encoding
                        _utf8_encode : function (string) {
                            string = string.replace(/\r\n/g,"\n");
                            var utftext = "";
                    
                            for (var n = 0; n < string.length; n++) {
                    
                                var c = string.charCodeAt(n);
                    
                                if (c < 128) {
                                    utftext += String.fromCharCode(c);
                                }
                                else if((c > 127) && (c < 2048)) {
                                    utftext += String.fromCharCode((c >> 6) | 192);
                                    utftext += String.fromCharCode((c & 63) | 128);
                                }
                                else {
                                    utftext += String.fromCharCode((c >> 12) | 224);
                                    utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                                    utftext += String.fromCharCode((c & 63) | 128);
                                }
                            }
                            return utftext;
                        },
                    
                        // private method for UTF-8 decoding
                        _utf8_decode : function (utftext) {
                            var string = "";
                            var i = 0;
                            var c = c1 = c2 = 0;
                    
                            while ( i < utftext.length ) {
                    
                                c = utftext.charCodeAt(i);
                    
                                if (c < 128) {
                                    string += String.fromCharCode(c);
                                    i++;
                                }
                                else if((c > 191) && (c < 224)) {
                                    c2 = utftext.charCodeAt(i+1);
                                    string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                                    i += 2;
                                }
                                else {
                                    c2 = utftext.charCodeAt(i+1);
                                    c3 = utftext.charCodeAt(i+2);
                                    string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                                    i += 3;
                                }
                            }
                            return string;
                        }
                    }
                    

                    另外,搜索"JavaScript base64 encoding" 会出现很多其他选项,以上是第一个。

                    【讨论】:

                    • 这在base64编码非标准时也很有用;在我的情况下,没有使用“/”字符,而“?”而是使用字符,这意味着即使在 Chrome 中 atob() 也不会解码传入的 base64 字符串。
                    • 小心这段代码 - 它试图将您的字符串解释为 UTF-8 编码的字符串。我们有一个例子,我们有一个二进制字符串(即字符串中的每个字符都应该被解释为一个字节),这个代码确实破坏了数据。阅读来源,卢克。
                    • 如果您使用来自 webtoolkito 信息的代码,请不要忘记版权: /** * * Base64 编码/解码 * webtoolkit.info * **/
                    • 为确保大多数二进制编码/解码安全所需的一切,以删除 utf8 编码方法中的有问题的 string = string.replace(/\r\n/g,"\n"); 语句。
                    • @Marius:我想知道他们为什么会首先包含string = string.replace(/\r\n/g,"\n");,哈哈。这就像“哦,让我们对这个字符串进行编码,但首先,我们为什么不完全没有充分的理由随机规范所有换行符”。在任何情况下都应该从课程中删除。
                    【解决方案25】:

                    如果你使用 Node.js,你可以这样做:

                    let a = Buffer.from('JavaScript').toString('base64');
                    console.log(a);
                    
                    let b = Buffer.from(a, 'base64').toString();
                    console.log(b);
                    

                    【讨论】:

                    • 这仅适用于 Node.js,不适用于浏览器中的 JavaScript
                    • 你是对的。抱歉,我只是通过 Node.js 测试。
                    【解决方案26】:

                    您可以使用btoa()atob() 与base64 编码相互转换。

                    对于这些函数接受/返回什么,cmets 似乎有些混淆,所以……

                    • btoa() 接受一个“字符串”,其中每个字符代表一个 8 位字节 - 如果您传递的字符串包含不能用 8 位表示的字符,it will probably break。这不是问题如果您实际上将字符串视为字节数组,但如果您尝试做其他事情,那么您必须先对其进行编码。

                    • atob() 返回一个“字符串”,其中每个字符代表一个 8 位字节——也就是说,它的值将介于 00xff 之间。这确实不是意味着它是 ASCII - 大概如果你使用这个函数,你希望使用二进制数据而不是文本。

                    另见:


                    这里的大多数 cmets 都已过时。你可以同时使用btoa()atob(),除非你支持非常过时的浏览器。

                    在这里查看:

                    【讨论】:

                    • 请注意,这也适用于 webkit 浏览器,例如 Safari。
                    • 请注意 Unicode 字符串的特殊注意事项:developer.mozilla.org/En/DOM/Window.btoa#Unicode_Strings btoa 和 atob 仅适用于基于 ASCII 的字符串。作为美国人,您可能不会注意到有什么不同……但是当您第一次使用重音字符时,您的代码会中断。
                    • 如果 str 是 UFT8,你应该使用 btoa(unescape(encodeURIComponent(str))))
                    • 查看我的编辑,@Triynko。这些不适用于处理 text, period.
                    • 读作b to aa to b,b代表二进制,a代表ASCII
                    【解决方案27】:

                    您可以在浏览器中使用 btoa()/atob(),但需要进行一些改进,如 https://base64tool.com/uncaught-domexception-btoa-on-window/https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/btoa 所述,以支持 UTF 字符串!

                    【讨论】:

                      【解决方案28】:

                      对于较新的浏览器,将 Uint8Array 编码为字符串,并将字符串解码为 Uint8Array。

                      const base64 = {
                          decode: s => Uint8Array.from(atob(s), c => c.charCodeAt(0)),
                          encode: b => btoa(String.fromCharCode(...new Uint8Array(b)))
                      };
                      

                      对于 Node.js,您可以使用以下代码将字符串、缓冲区或 Uint8Array 编码为字符串,并将字符串、缓冲区或 Uint8Array 解码为缓冲区。

                      const base64 = {
                          decode: s => Buffer.from(s, 'base64'),
                          encode: b => Buffer.from(b).toString('base64')
                      };
                      

                      【讨论】:

                        【解决方案29】:

                        这是@user850789 的AngularJS Factory 版本:

                        'use strict';
                        
                        var ProjectNameBase64Factory = angular.module('project_name.factories.base64', []);
                        
                        ProjectNameBase64Factory.factory('Base64', function () {
                            var Base64 = {
                                // private property
                                _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
                        
                                // public method for encoding
                                encode: function (input) {
                                    var output = "";
                                    var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
                                    var i = 0;
                        
                                    input = Base64._utf8_encode(input);
                        
                                    while (i < input.length) {
                        
                                        chr1 = input.charCodeAt(i++);
                                        chr2 = input.charCodeAt(i++);
                                        chr3 = input.charCodeAt(i++);
                        
                                        enc1 = chr1 >> 2;
                                        enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
                                        enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
                                        enc4 = chr3 & 63;
                        
                                        if (isNaN(chr2)) {
                                            enc3 = enc4 = 64;
                                        } else if (isNaN(chr3)) {
                                            enc4 = 64;
                                        }
                        
                                        output = output +
                                                 Base64._keyStr.charAt(enc1) + Base64._keyStr.charAt(enc2) +
                                                 Base64._keyStr.charAt(enc3) + Base64._keyStr.charAt(enc4);
                        
                                    }
                        
                                    return output;
                                },
                        
                                // public method for decoding
                                decode: function (input) {
                                    var output = "";
                                    var chr1, chr2, chr3;
                                    var enc1, enc2, enc3, enc4;
                                    var i = 0;
                        
                                    input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
                        
                                    while (i < input.length) {
                        
                                        enc1 = Base64._keyStr.indexOf(input.charAt(i++));
                                        enc2 = Base64._keyStr.indexOf(input.charAt(i++));
                                        enc3 = Base64._keyStr.indexOf(input.charAt(i++));
                                        enc4 = Base64._keyStr.indexOf(input.charAt(i++));
                        
                                        chr1 = (enc1 << 2) | (enc2 >> 4);
                                        chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
                                        chr3 = ((enc3 & 3) << 6) | enc4;
                        
                                        output = output + String.fromCharCode(chr1);
                        
                                        if (enc3 != 64) {
                                            output = output + String.fromCharCode(chr2);
                                        }
                                        if (enc4 != 64) {
                                            output = output + String.fromCharCode(chr3);
                                        }
                        
                                    }
                        
                                    output = Base64._utf8_decode(output);
                        
                                    return output;
                        
                                },
                        
                                // private method for UTF-8 encoding
                                _utf8_encode: function (string) {
                                    string = string.replace(/\r\n/g, "\n");
                                    var utftext = "";
                        
                                    for (var n = 0; n < string.length; n++) {
                        
                                        var c = string.charCodeAt(n);
                        
                                        if (c < 128) {
                                            utftext += String.fromCharCode(c);
                                        }
                                        else if ((c > 127) && (c < 2048)) {
                                            utftext += String.fromCharCode((c >> 6) | 192);
                                            utftext += String.fromCharCode((c & 63) | 128);
                                        }
                                        else {
                                            utftext += String.fromCharCode((c >> 12) | 224);
                                            utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                                            utftext += String.fromCharCode((c & 63) | 128);
                                        }
                        
                                    }
                        
                                    return utftext;
                                },
                        
                                // private method for UTF-8 decoding
                                _utf8_decode: function (utftext) {
                                    var string = "";
                                    var i = 0;
                                    var c = 0, c2 = 0, c3 = 0;
                        
                                    while (i < utftext.length) {
                        
                                        c = utftext.charCodeAt(i);
                        
                                        if (c < 128) {
                                            string += String.fromCharCode(c);
                                            i++;
                                        }
                                        else if ((c > 191) && (c < 224)) {
                                            c2 = utftext.charCodeAt(i + 1);
                                            string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                                            i += 2;
                                        }
                                        else {
                                            c2 = utftext.charCodeAt(i + 1);
                                            c3 = utftext.charCodeAt(i + 2);
                                            string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                                            i += 3;
                                        }
                        
                                    }
                                    return string;
                                }
                            };
                            return Base64;
                        });
                        

                        【讨论】:

                        【解决方案30】:

                        对于我的项目,我仍然需要支持 IE7 并使用大量输入进行编码。

                        根据 Joe Dyndale 提出的代码以及 Marius 在评论中的建议,可以通过使用数组而不是字符串构造结果来提高 IE7 的性能。

                        这里是编码的例子:

                        var encode = function (input) {
                            var output = [], chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0;
                        
                            input = _utf8_encode(input);
                        
                            while (i < input.length) {
                        
                                chr1 = input.charCodeAt(i++);
                                chr2 = input.charCodeAt(i++);
                                chr3 = input.charCodeAt(i++);
                        
                                enc1 = chr1 >> 2;
                                enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
                                enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
                                enc4 = chr3 & 63;
                        
                                if (isNaN(chr2)) {
                                    enc3 = enc4 = 64;
                                } else if (isNaN(chr3)) {
                                    enc4 = 64;
                                }
                        
                                output.push(_keyStr.charAt(enc1));
                                output.push(_keyStr.charAt(enc2));
                                output.push(_keyStr.charAt(enc3));
                                output.push(_keyStr.charAt(enc4));
                        
                            }
                        
                            return output.join("");
                        };
                        

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 2015-06-04
                          • 1970-01-01
                          • 2012-11-12
                          • 2012-01-19
                          • 2021-11-27
                          • 2021-09-22
                          • 2019-08-16
                          相关资源
                          最近更新 更多