escape,encodeURI,encodeURIComponent有什么区别?

首先,escape/unescape 已经废弃,应当避免使用。

  • The deprecated escape() method computes a new string in which certain characters have been replaced by a hexadecimal escape sequence. Use encodeURI or encodeURIComponent instead.
  • The deprecated unescape() method computes a new string in which hexadecimal escape sequences are replaced with the character that it represents. The escape sequences might be introduced by a function like escape. Because unescape is deprecated, use decodeURI or decodeURIComponent instead.

根据 MDN 的说明,escape 应当换用为 encodeURIencodeURIComponentunescape 应当换用为 decodeURIdecodeURIComponent

那么, encodeURI/decodeURIencodeURIComponent/decodeURIComponent 的区别是什么?

encodeURI会对非ACSII、数字以及- _ . ! ~ * ' ( )符号和URI分隔符;/?:@&=+$,#之外的所有字符进行转码。

encodeURI(“http://www.baidu.com/pa th/我的”)
// http://www.baidu.com/pa%20th/%E6%88%91%E7%9A%84

encodeURIComponentencodeURI的作用几乎相同,区别在与encodeURIComponent会对URI分隔符;/?@$=+#等进行转码。

encodeURIComponent(“http://www.baidu.com/pa th/我的”)
// http%3A%2F%2Fwww.baidu.com%2Fpa%20th%2F%E6%88%91%E7%9A%84

一些场景

  1. 一般需要get请求的方式在地址栏中拼接一些参数,但是参数中如果出现#,/,&这些字符,就必须要用decodeURIComponent了,不然这些特殊字符会导致我们接收参数的错误

    // 传code=2020dba#abc 到 http://www.xxx.com
    var codeVal = encodeURI('2020dba#abc');
    var url = 'http://www.xxx.com?code=' + codeVal;
    console.log(url);
    // http://www.xxx.com?code=2020dba#abc
    
    // http://www.xxx.com接收参数
    console.log(location.search)  //"?code=2020dba";
    
    

    这时候拿到的code参数明显是错误的,被特殊字符#截断了,下面用decodeURIComponent方法:

    var codeVal = encodeURI('2020dba#abc');
    var url = 'http://www.baidu.com?code=' + codeVal;
    console.log(url);
    // http://www.xxx.com?code=2020dba%23abc
    
    // http://www.xxx.com接收参数
    console.log(location.search)  //?code=2020dba%23abc;
    decodeURIComponent("?code=2020dba%23abc")  //"?code=2020dba#abc"
    
  2. 进行url跳转时可以整体使用encodeURI

    Location.href=encodeURI("http://localhost:8007/user/login?code=%E4%B8%AD%E5%9B%BD%E4%BA%BA");
    

Base64 转码

以下摘自阮一峰老师博客

有时,文本里面包含一些不可打印的符号,比如 ASCII 码0到31的符号都无法打印出来,这时可以使用 Base64 编码,将它们转成可以打印的字符。另一个场景是,有时需要以文本格式传递二进制数据,那么也可以使用 Base64 编码。

所谓 Base64 就是一种编码方法,可以将任意值转成 0~9、A~Z、a-z、+/这64个字符组成的可打印字符。使用它的主要目的,不是为了加密,而是为了不出现特殊字符,简化程序的处理。

JavaScript 原生提供两个 Base64 相关的方法。

  • btoa():任意值转为 Base64 编码
  • atob():Base64 编码转为原来的值
var string = 'Hello World!';
btoa(string) // "SGVsbG8gV29ybGQh"
atob('SGVsbG8gV29ybGQh') // "Hello World!"

注意,这两个方法不适合非 ASCII 码的字符,会报错。

btoa('你好') // 报错

要将非 ASCII 码字符转为 Base64 编码,必须中间插入一个转码环节,再使用这两个方法。

function b64Encode(str) {
  return btoa(encodeURIComponent(str));
}

function b64Decode(str) {
  return decodeURIComponent(atob(str));
}

b64Encode('你好') // "JUU0JUJEJUEwJUU1JUE1JUJE"
b64Decode('JUU0JUJEJUEwJUU1JUE1JUJE') // "你好"

总结

encodeURI 和 encodeURIComponent 的区别在于需要转义的字符范围不一样:

encodeURI不编码字符有82个:! ' ( ) * - . _ ~ 0-9 a-z A-Z 和 URI分隔符/ : ; = ? @ # $ & + ,

encodeURIComponent不编码字符有71个(不包括URL分隔符):! ' ( ) * - . _ ~ 0-9 a-z A-Z

encodeURIencodeURIComponent的编码方式都是相同的,先将中文等需要编码的字符进行进行utf-8编码,然后在 UTF-8 的每个字节码前加上一个 「%」的,所以如果给后台传递参数需要使用encodeURIComponent时需要后台解码对utf-8支持(form中的编码方式和当前页面编码方式相同)

实际使用上,encodeURIencodeURIComponent的区别在于前者被设计来用于对完整URL进行URL Encode,于是URL中的功能字符,比如&, ?, /, =等等这些并不会被转义;而后者被设计来对一个URL中的值进行转义,会把这些功能字符也进行转义。

由此可知,前端开发中用到比较多的应该是 encodeURIComponent/decodeURIComponent。例如下面这个将 URL Search 中的参数转化为对象的方法:

var parseUrlSearch = function() {
  var query = window.location.search.slice(1);
  var result = {};
  query.split("&").forEach(function(part) {
    var item = part.split("=");
    result[item[0]] = decodeURIComponent(item[1]);
  });
  return result;
};

参考

https://www.cnblogs.com/jhxk/articles/1634359.html

https://zaozaool.github.io/2015/10/01/JavaScript学习笔记之-encodeURI-encodeURIComponent-escape-decodeURI-decodeURIComponent-unescape区别/

https://www.zhihu.com/question/21861899

https://javascript.ruanyifeng.com/grammar/string.html#toc6

你可能感兴趣的:(JavaScript)