likes
comments
collection

为什么要对URL进行编码

作者站长头像
站长
· 阅读数 19
  1. 为什么要使用encodeURIComponent等对URL进行编码
  2. 浏览器地址栏上的https://www.google.com/search?q=中&文复制链接为啥变成看不懂的东西https://www.google.com/search?q=%E4%B8%AD&%E6%96%87

假设你对啥是编码有一定的了解,没有请戳 (从'𠮷'.length !== 1去理解js中的字符串编码)看看计算机的基础知识

原因有两个

(1) url的编码格式采用的是ASCII码,说明你不能在Url中包含任何非ASCII字符 (2) 网络标准RFC 1738做了硬性规定,决定了如何正确解析url

"只有字母和数字[0-9a-zA-Z]、一些特殊符号"$-_.+!*'(),"[不包括双引号]、以及某些保留字"(有特殊用途";","/", "?", ":", "@", "=" "&"等)才可以不经过编码直接用于URL。" --- 来自 关于URL编码 也就说明双引号作为ASCII字符的合法字符,为什么我们还是得对双引号编码,其次url通过key=value键值对来传参,键值对之间以&符号分隔,如果你的key,value中也存在=&,就会造成造成接收Url的服务器解析错误

js中对url编码的函数

encodeURI()

对整个URL进行编码,不对A-Z a-z 0-9 ; , / ? : @ & = + $ - _ . ! ~ * ' ( ) #进行编码。编码后,它输出符号的utf-8形式,并且在每个字节前加上%,所以Url编码通常也被称为百分号编码(Url Encoding,also known as percent-encoding),%百分号加上两位的字符(十六进制)的utf-8编码

相应的解码函数decodeURI

let url = "http://www.example.com/path/page?q=3&v=中文#anchor"
encodeURI(url)
// Output: 'http://www.example.com/path/page?q=3&v=%E4%B8%AD%E6%96%87#anchor'

encodeURI()存在的问题: 当用户输入的含有&,=等字符作为查询选项,不对其编码会导致前后端对url的解析不正确

// 直接将用户输入拼接在url中,并对整个url进行编码
let url = 'https://www.google.com/search?q=中&文'
let encodeUrl = encodeURI(url)
let query = new URLSearchParams(encodeUrl.split("?")[1])
query.get("q") // "中"  解析不正确

encodeURIComponent()

与encodeURI()的区别是,它用于对URL的组成部分进行个别编码,而不用于对整个URL进行编码,不对 A-Z a-z 0-9 - _ . ! ~ * ' ( )。其他与encodeURI一样。

相应的解码函数decodeURIComponent

// 对用户值输入采用decodeURIComponent进行编码
let url = `https://www.google.com/search?q=${encodeURIComponent('中&文')}`
let query = new URLSearchParams(url.split("?")[1])
query.get("q") // '中&文' 正确解析

扩展

浏览器会对url进行自动编码

当你复制https://www.google.com/search?q=中&文到浏览器,再复制下这个地址就变成https://www.google.com/search?q=%E4%B8%AD&%E6%96%87,得到的结果有点encodeURI的味道,但是就阮大大的测试所说,实在太混乱了,不同的操作系统、不同的浏览器、不同的网页字符集,将导致完全不同的编码结果。

为什么要对URL进行编码

像这种用户直接在浏览器输入的数据(浏览器发出HTTP请求)我们编不了码,但是由我们自己控制生成HTTP请求(Ajax调用),跳转其他页面(拼接参数)都可以对url的component经过编码,带来更多的可控性

为什么要对URL进行编码

参考