相同点:
不同点:
所以:如果需要对整个 URI 进行编码,应该使用 encodeURI() 方法;如果需要对查询字符串参数进行编码,应该使用 encodeURIComponent() 方法
const url = 'http://example.com/path/to/page?name=小明&age=18'
const search = url.split('?')[1]
const params = {}
search.split('&').forEach(param => {
const [key, value] = param.split('=')
params[key] = value
})
const encodedName = encodeURIComponent(params.name)
const encodedAge = encodeURIComponent(params.age)
const encodeSearchParams = `http://example.com/path/to/page?name=${encodedName}&age=${encodedAge}`
const encodeUrl = encodeURI(url)
// 编码后如果想得到原始字符串可以使用 decodeURI 和decodeURIComponent 解码
console.log(decodeURIComponent(encodeSearchParams))
console.log(decodeURI(encodeUrl))
new URL我们可以使用 new URL() 构造函数创建 URL 对象并访问其属性方法:
const url = new URL('https://www.example.com/path/file?query=value#fragment')
console.log(url.protocol) // 输出:https:
console.log(url.host) // 输出:www.example.com
console.log(url.pathname) // 输出:/path/file
console.log(url.search) // 输出:?query=value
console.log(url.hash) // 输出:#fragment
URL 对象还提供了一些方法,例如 toString() 方法可以将 URL 对象转换为字符串,searchParams 属性可以访问查询字符串参数等:
const url = new URL('https://www.example.com/path/file?name=张三&age=20')
console.log(url.searchParams.get('name')) // 张三
console.log(url.searchParams.get('age')) // 20
// 下面这种形式也能获取 search
const params = new URLSearchParams(location.search)
const name = params.get('name')
const age = params.get('age')
url.pathname = '/new/path'
console.log(url.toString()) // https://www.example.com/new/path?name=%E5%BC%A0%E4%B8%89&age=20
更多方法:
btoa() 方法用于将字符串转换为 Base64 编码。它接受一个字符串作为参数,返回一个 Base64 编码的字符串。例如:
const str = 'Hello world'
const encodedStr = btoa(str)
console.log(encodedStr) // SGVsbG8gd29ybGQ=
atob() 方法用于将 Base64 编码的字符串解码为原始字符串。它接受一个 Base64 编码的字符串作为参数,返回一个原始字符串。例如:
const encodedStr = 'SGVsbG8gd29ybGQ='
const str = atob(encodedStr)
console.log(str) // Hello world
需要注意的是,btoa() 和 atob() 方法只能处理 ASCII 字符串(包含 128 个字符,其中包括英文字母、数字、标点符号和一些控制字符),如果字符串中包含非 ASCII 字符,需要先将其转换为 UTF-8 编码的字节数组,再进行 Base64 编码。例如
const str = '你好 世界'
const utf8Bytes = new TextEncoder().encode(str)
const encodedStr = btoa(String.fromCharCode(...utf8Bytes))
console.log(encodedStr) // 5L2g5aW9IOS4lueVjA==
同样地,如果需要将 Base64 编码的字符串解码为非 ASCII 字符串,需要先将其解码为字节数组,再将字节数组转换为字符串。例如:
let encodedStr = '5L2g5aW9IOS4lueVjA=='
let bytes = new Uint8Array(
atob(encodedStr)
.split('')
.map(c => c.charCodeAt(0))
)
let str = new TextDecoder().decode(bytes)
console.log(str) // 你好 世界
应用场景:
在前端开发中,经常需要将图片或音频等二进制数据转换为 Base64 编码的字符串,以便在网页中直接显示或传输
可以使用 btoa() 方法将二进制数据编码为 Base64 字符串,例如:
// 通过fetch方法获取远程服务器上的图片文件,并将响应结果转换为Blob对象
const blob = await fetch('example.png').then(res => res.blob());
// 创建一个Promise对象,将Base64编码后的图片数据存储在变量base64中
const base64 = await new Promise(resolve => {
// 创建一个FileReader对象,用于将Blob对象中的数据转换为Base64编码的字符串
const reader = new FileReader();
// 当FileReader对象读取完成时触发onload事件
reader.onload = () => {
// 将DataURL中的Base64编码字符串取出,并将其存储在变量base64中
resolve(reader.result.split(',')[1]);
};
// 将Blob对象中的数据读取为DataURL
reader.readAsDataURL(blob);
});
某些API的响应结果可能包含二进制数据,例如图片或音频等,这些数据可以通过 btoa() 方法进行 Base64 编码,然后在网络传输中传递。例如:
// 使用fetch方法获取远程服务器上的图片文件example.png
fetch('example.png')
// 将响应结果转换为ArrayBuffer对象
.then(res => res.arrayBuffer())
// 将ArrayBuffer对象转换为Base64编码字符串
.then(buffer => {
// 将ArrayBuffer对象转换为Uint8Array数组,便于后续处理
const uint8Array = new Uint8Array(buffer);
// 使用btoa方法将Uint8Array数组转换为Base64编码字符串
const base64 = btoa(
// 使用reduce方法将Uint8Array数组中的数据转换为ASCII字符串
uint8Array.reduce((data, byte) => data + String.fromCharCode(byte), '')
);
// 将Base64编码后的字符串输出到控制台
console.log(base64)
});
由于 Base64 编码后的字符串只包含 ASCII 字符,因此可以安全地传输或存储到不支持二进制数据的地方(如URL、XML等),以避免出现数据传输或存储时的格式问题。例如:
// 创建一个Uint8Array数组,包含 ASCII 编码的字符串"Hello World"
const data = new Uint8Array([0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64]);
// 将Uint8Array数组转换为Base64编码字符串
const base64 = btoa(
// 使用reduce方法将Uint8Array数组中的数据转换为ASCII字符串
data.reduce((data, byte) => data + String.fromCharCode(byte), '')
);
// 将Base64编码后的字符串作为查询字符串的值,拼接成完整的URL
const url = `https://example.com/api?data=${encodeURIComponent(base64)}`
要注意的是,由于 Base64 编码后的字符串通常比原始二进制数据大约33%,因此在传输或存储大量二进制数据时,需要考虑编码后的数据大小问题,以免影响性能。