URL中乱七八糟的字符讲解,来源以及如何解决

JSON 2020-12-30 18:24:27 10572

当我们的  URL  中包含中文、或者说包含一些非英文字母、数字、符号的时候,就会出现一堆百分号加字符串数字的内容,而且很长。

比如这张图片地址:

http://fileupload-upyun.test.upcdn.net/images/%E5%90%91%E6%97%A5%E8%91%B51.jpg

实际是:

http://fileupload-upyun.test.upcdn.net/images/向日葵1.jpg

你打开从浏览器看也是中文的“向日葵”,但是复制出来就是urlencode的编码结果。因为浏览器有保护措施,会修改您复制的内容,方便你发给其他人不会丢失信息。就这样一些聊天工具也继承了这一默认的标准。


URL - 网络资源定位符

通过互联网来访问网络中资源的时候,最常见就是通过浏览器输入资源的 URL 地址来进行访问。

URL(Uniform Resource Locator),是互联网中的一个核心概念,官方名称叫做统一资源定位符。简单的来说,URL 就是一个由网站开发者给资源在互联网上分配的地址。一般来说,每个有效的 URL 都指向单独的一个资源,这个资源可以是HTML 页面、CSS 文档,又或者是一幅图像等。

一个 URL 由不同的部分组成,其中一些是必须的,而另一些是可选的。下面我们来看下 URL 的具体组成部分:


上图就是完整的 URL 结构展示。很多时候其中的一些部分是用不到的,例如 user information。作为参考,我们可以来看一下又拍云存储的 URL 地址。

https://www.upyun.com/products/file-storage

  • https:// ,请求协议(scheme),指定了浏览器需要使用何种协议来与目标服务器进行通讯。常见的协议有 HTTP 和 HTTPS。
  • www.upyun.com,域名(host),表明请求的资源所在的服务器地址。
  • /products/file-storage ,资源路径地址(path),服务器通过路径来确认访问资源在服务器上的哪个位置。
  • 一般常见的 URL 地址由这三个部分组成,其余的部分根据开发的需要,可以进行自定义。
了解 URL 的概念后,就知道二狗子的图片链接 http://fileupload-upyun.test.upcdn.net/images/向日葵1.jpg 的由来了。通过这个地址,婷婷可以访问到二狗子服务器上拍摄的向日葵图片。但是,为什么二狗子复制了浏览器地址栏中的地址,发送给婷婷的时候,URL 却变成了 http://fileupload-upyun.test.upcdn.net/images/%E5%90%91%E6%97%A5%E8%91%B51.jpg 了呢?

奇怪的字符 - URL 编码

我们可以看到,二狗子发给婷婷的链接,改变了的部分属于 URL 的 path 部分,而且,英文部分其实没有改动,只有中文的部分被转成 %XX 的这种编码格式了。

虽然,这不会影响图片的打开,地址依旧是有效的。但是为什么浏览器要把中文转换成这种奇怪的形式呢?

我们先来看一个例子。如果访问下面这个 URL 链接:

 https://www.baidu.com/s?wd=?#!

这是使用百度进行搜索的一个链接,/s 后面跟着的 ? 代表请求参数(query),也就是我们想向请求的服务器提交一些参数。wd 为百度规定的查询参数名,wd 后边跟着的就是需要搜索的内容。

我们想搜索 ?#! 这个内容,可是当你复制这个链接放在浏览器中打开时,会发现一个问题,百度仅仅是搜索了 ? 这个内容,#! 不见了。


为什么呢?如果你仔细看上面那张 URL 的构成图,会发现 URL 结构中还有一个锚点(fragment)的部分,分隔符号就是 #。

所以这里就会出现一个问题,我们的业务需求是将 # 当做一个普通文本来进行搜索,但是 # 在 URL 中有特定的意思,所以浏览器就遇到了一个解释歧义的问题。

这就引申出一个问题,URL 在数据传递中,如果存在用作分隔符等特殊作用的保留字符怎么办?

在实际的业务场景中,会经常碰到一些在 URL 中有歧义性的数据,为了避免解释错误,开发者想出了一个解决方法,就是对这些数据进行一定的处理,从而解决歧义的问题。处理的方法有很多种,最常用的处理方式,就是对歧义性的数据进行 URL 百分号编码。

哪些是会引起歧义的数据呢?

根据 RFC 3986(https://tools.ietf.org/html/rfc3986#appendix-A)的规定,我们可以得到下面的结果。

  1. 不在 ASCII 码范围内的字符 (URL 使用 ASCII 码进行编解码)
  2. ASCII 码中不可显示的字符
  3. URL 中规定的保留字符
  4. 不安全字符(传输环节中可能会被不正确处理),如空格、引号、尖括号等

保留字符由组件分隔符(gen-delims)和子组件分隔符(sub-delims)组成,这些字符在 URL 中都有特殊的意义:

Reserved = gen-delims / sub-delims

URL 中可以直接使用的非保留字符则有:

Unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"

这下子我们就了解了,为什么 URL 中有时会出现奇怪的字符,很多时候浏览器会自动帮我们做编码和解码的操作。就像“向日葵”的 URL 一样,中文部分因为并不在 ASCII 码中,于是浏览器进行 URL 百分号编码的形式来进行访问。


(又拍云服务名的合法范围就是在非保留字符中获取,而不能指定为任意字符)

编码的形式

最常见的编码形式就是百分号编码(pct-encoded),这也是浏览器默认的编码形式。

pct-encoded = "%" HEXDIG HEXDIG


(感兴趣的同学可以参考百分号编码 https://zh.wikipedia.org/zh-hans/%E7%99%BE%E5%88%86%E5%8F%B7%E7%BC%96%E7%A0%81 条目)

各个编程语言中也有相对应的方法可以进行百分号编码,例如 JavaScript 中就提供了多种编码方法,常用的有 encodeURI 和 encodeURIComponent 两个方法。


△ 中文百分号编码的结果展示

在日常开发使用中,我们使用的开发库对 URL 编码的判断标准可能并不相同,这是因为这些库所面临的网络环境中,对于特殊字符的安全处理策略各有判断,这也会导致 URL 中如果存在一些特殊字符,开发、访问过程中可能就会出现一些奇怪的问题。在这里也建议大家使用非保留字符来设计自己程序中 URL 部分,避免一些不必要的 BUG 产生。





版权所属:SO JSON在线解析

原文地址:https://www.sojson.com/blog/384.html

转载时必须以链接形式注明原始出处及本声明。

本文主题:

如果本文对你有帮助,那么请你赞助我,让我更有激情的写下去,帮助更多的人。

关于作者
一个低调而闷骚的男人。
相关文章
SOJSON 拓展服务器被DDos攻击了一晚上,是如何解决的?
如何判断字符串是JSON数组还是JSON对象
如何把自己的Jar包上传到 maven 官方仓库,Maven上传图文讲解
IOS urldecode 如何解码后,解码后“+”(加号)和空格处理方式
MD5如何解密?
MySQL数据库存储过程字符集问题,乱码的解决办法
json对象与json字符串的转换方法
如何解析JSON数据(详细解答)
JS “is not defined” 如何判断defined,defined和undefined 的区别
document.domain解决跨域问题,详细讲解
最新文章
Java获取浏览器请求头(User-Agent),分析浏览器信息,系统信息的几种办法。 137027
最热文章
Java获取浏览器请求头(User-Agent),分析浏览器信息,系统信息的几种办法。 137027
支付扫码

所有赞助/开支都讲公开明细,用于网站维护:赞助名单查看

查看我的收藏

正在加载... ...