URL 只能使用英文字母、阿拉伯数字和某些标点符号,不能使用其他文字和符号。网络标准RFC 1738做了硬性规定:

“…Only alphanumerics [0-9a-zA-Z], the special characters “$-_.+!*’(),” [not including the quotes - ed], and reserved characters used for their reserved purposes may be used unencoded within a URL.”

“只有字母和数字[0-9a-zA-Z]、一些特殊符号”$-_.+!*’(),”[不包括双引号]、以及某些保留字,才可以不经过编码直接用于URL。”

为什么需要 URL 编码

秉承着「知其然还要知其所以然的态度」,先来思考下什么情况下,我们需要编码?

  • 这是隐私数据,不是适合明文传输
  • 编码后可以有效的压缩传输的数据量
  • 包含某些会引起歧义的字符

在 URL 中之所以要编码,就是因为在传输的内容跟预留字符(&、=、?)有相同的时候,会造成 URL 服务器的解析错误,比如参数的 key = value 键值对中,在 value 中包含 &、=、?等几种预留字符的时候,你让服务器如何解析?

哪些字符需要编码

保留字

URL 可以划分成若干组件、协议、主机、路径等。

  • 一些字符用来分隔不同的组件,比如「:/?#@」
  • 一些字符在每个组件中分隔的,比如 & =

不安全字符

还有些字符,当它们直接放在 URL 中时,可能会引起解释程序的歧义

  • 空格——URL 在传输过程中,用户排版时,文本处理程序在处理 URL的过程中,都可能引入无关紧要的空格
  • 引号和<>——通常用于在普通文本中起到分隔 URL 的作用
  • # 用于标示书签或锚点
  • % 本身用作对不安全字符编码时的特殊字符,所以本身需要编码
  • {}[]|^ 某些网关或者传输代理会篡改这些字符

注意

由于历史原因,目前存在一些不标准的编码实现,比如对于符号~ 虽然RFC3986文档规定,对于~不需要编码,但是一些老的网关或者传输代理会。比如[]也被编码了。

对于 URL 中的合法字符,编码和不编码是等价的,但是对于上面提到的那些字符,如果不编码,那它们可能会造成 URL 语义的不同。因此,对于 URL 而言,只有普通英文字符和数字、特殊字符和保留字符,能出现在未经编码的 URL 中,其他字符都需要经过编码。

编码规则

先介绍几种存在的编码规则,详细的内容可以看《字符编码笔记》:

  • ASCII 码: ASCII 码一共规定 128 个字符编码(包括 32 个不能打印的控制符号)
  • 非 ASCII 码:英语 128 个符号编码是够的,但用来表示其他语言,128 个符号是不够的。一些欧洲国家决定利用字节中闲置的最高位编入新的符号,前 128 位是相同的,后面的 128 位不同
  • unicode:将世界上所有的符号都纳入其中,每一个符号都给予一个独一无二的编码,消除乱码问题。Unicode 只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。
  • UTF-8: UTF-8 就是在互联网上使用最广的一种 Unicode 的实现方式。

如何编码

URL 编码通常被称为百分号编码(URL Encoding, also know as percent-encoding),因为它的编码方式很简单,使用 % 加上两个字符代表一个字节的16进制形式:

URL 编码默认使用的字符集是 ASCII

  • a 在 ASCII 中对应的字节是 0x61,经过 URL 编码后得到就是 %61
  • @ 在 ASCII 中对应的字节是 0x40,经过 URL 编码后得到就是 %40
  • 对于非 ASCII 字符,需要使用 ASCII 字符集的超集进行编码得到相应的字符,然后再对每个字符执行百分号编码
  • 对于 Unicode 字符,RFC 文档建议使用 UTF-8 对其进行编码得到相应的字节,然后再对每个字节执行百分号编码

GET vs POST

在被问到 http GET 和 POST 的区别的时候,普遍给出的回答可能是:

  • GET 的参数包含在 URL 中,POST 的参数通过 request body 进行传递
  • 在 restful api 规则中, GET 用于从服务器获取指定资源,POST 用于在服务器创建资源;GET 操作是安全的,不管进行多少次操作,资源的状态都不会改变,POST 操作不是安全的,重复发起多次 POST 的请求,会导致服务器创建若干资源。

你真的觉得这么回答就是能拿满分了吗?义务教育不是教育过我们不会的时候要多写点答案,老师还会有个感情分给你,让我们再想想。

  • GET 在浏览器回退的时是无害的,而 POST 会再次提交请求
  • GET 产生的 URL 可以被 Bookmark,而 POST 不可以
  • GET 请求会被浏览器主动 cache,而 POST 不会,除非手动设置
  • GET 请求只能进行 URL 编码(就是上面说的 URL 编码),而 POST 支持多种编码方式
  • GET 请求参数会被完整保留在浏览器的历史记录里,而 POST 中的参数不会被保留
  • GET 请求在URL 中传送的参数是有长度限制的,而 POST 没有
  • 对于参数的数据类型,GET 只接受 ASCII 字符,而 POST 没有
  • GET 比 POST 更不安全,因为参数直接暴露在 URL 上,所以不能用来传递敏感信息

对于能轻松列举以上不同点的同学,是需要奖励大红花的,毕竟笔者也是抄了别人的文章才知道的,不过这还不是最终答案,思考问题更深入一些,它们的底层是不是有什么不一样的地方?

我是谁: GET 和 POST 是什么?

  • HTTP 协议中的两种发送请求的方法

我从哪里来:HTTP 是什么?

  • HTTP 是基于 TCP/IP 的关于数据如何在万维网中通信的协议。
  • GET 和 POST 底层都是 TCP 连接, 能做的事情也是相同的。如果你想给 GET 加上 request body, 给 POST 带上 URL 参数,技术上来说也没什么不行的。

「99%的人都理解错了HTTP中GET与POST的区别」中提出了一个很形象的比喻,在你万维网世界中,将 TCP 比喻成汽车用来运输数据,为了避免送急件的阻塞满载货物的汽车,又提出了交通规则 HTTP 。 HTTP 给汽车运输规定了不同的服务类别,包括 GET、POST、PUT、 DETETE等。浏览器可以想象成运输公司,不同的运输公司对汽车运输货物的量是有要求的,数据量太大对浏览器和服务器都会造成很大负担。

业界不成文的规定是,(大多数)浏览器通常都会限制url长度在2K个字节,而(大多数)服务器最多处理64K大小的url。超过的部分,恕不处理。

终极大 boos 来了, GET 和 POST 还有一个很大的不同,简单的说:

  • GET 产生一个 TCP 数据包,POST 产生两个 TCP 数据包。
  • 更容易理解的版本:
    • 对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据)
    • 而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)

参考资料

  • URL编码
  • 关于URL编码
  • 99%的人都理解错了HTTP中GET与POST的区别
  • golang中使用url encoding遇到的小坑

http GET 请求 URL 总结相关推荐

  1. 如何解决请求URL长度超过配置的maxurlLength值问题

    当我们批量请求的数据太多时,会出现请求的url长度超过配置maxurllength值的问题(比如一次性操作1000条数据) 1.问题描述: 我在进行批量选择单据进行发送时,出现这个问题(批量500条) ...

  2. php批量请求url_php请求url的方法小结

    本文主要给大家介绍关于php中请求url的五种方法,分别是用fopen()函数.file()函数.file_get_contents()函数.curl() 请求远程url数据和exec() 执行命令行 ...

  3. openresty获取nginx请求url中的所有参数

    获取请求url中的所有参数:vi test.lua b传两个值:

  4. 高仿真的类-请求url

    /*** 请求url**/ @Target({ElementType.METHOD,ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Do ...

  5. java 该改变request url_如何在Java中使用servlet过滤器来更改传入的servlet请求URL?...

    如何使用servlet过滤器来更改传入的servlet请求URL web.xml 至 web.xml ? 更新:根据BalusC的以下步骤,我想出了以下代码: public class UrlRewr ...

  6. python如何获取请求的url_听说你在学习:如何通过代码请求URL地址

    最近比较忙碌,都没有时间更新公众号文章,表示比较惭愧.最近翻看了一下自己的博客,发现这篇文章的内容还是挺实用,所以,想分享给大家,欢迎阅读.在后续,我会从一个范围的角度进行编写一系列文章,便于各位深层 ...

  7. android url拼接参数,【Tech-Android-Other】高效拼接一个GET请求URL

    高效拼接一个GET请求URL private String getUrl(HashMap params) { String url = Constants.URL_CS_DATA; // 添加url参 ...

  8. python get请求 url传参_requests的get请求url参数、url重定向处理及cookies

    需求:在百度搜索www.python66.com,然后将搜索结果保存到文件bd_python66.html 百度搜索的url:https://www.baidu.com/s?wd=搜索词 params ...

  9. Spring MVC 之 请求url 带后缀的情况

    RequestMappingInfoHandlerMapping 在处理http请求的时候, 如果 请求url 有后缀,如果找不到精确匹配的那个@RequestMapping方法. 那么,就把后缀去掉 ...

  10. 微信公众号平台服务器配置请求url超时,绑定微信公众平台提示请求URL超时怎么办...

    绑定微信公众平台提示"请求URL超时"解决办法,这个问题很多朋友遇到过,绑定微信公众平台提示请求URL超时解决办法其实很简单,下面由学习啦小编告诉你! 绑定微信公众平台提示请求UR ...

最新文章

  1. 焦虑的 BAT、不安的编程语言,揭秘程序员技术圈生存现状!
  2. R语言基于Bagging算法(融合多个决策树)构建集成学习Bagging分类模型、并评估模型在测试集和训练集上的分类效果(accuray、F1、偏差Deviance):Bagging算法与随机森林对比
  3. 皮一皮:这个单人可玩推理真是太好玩了...
  4. Android 开源框架之 Android-async-http 源码解读
  5. spring boot:创建一个简单的web(maven web project)
  6. Angular rxjs Subject笔记
  7. 16、document的_source元数据以及定制返回结果解析
  8. Ant design pro引入Echarts报错:TypeError: Cannot read property 'x_data' of undefined
  9. beeline hiveserver2 start
  10. List 去除重复数据的 5 种正确姿势!
  11. as3实现(可以操纵的)真正的由惯性导致的漂移
  12. 如何解决It's likely you're attempting to run Eclipse using the JRE instead of the JDK
  13. Deep Glow mac(AE高级辉光特效插件)支持AE2022
  14. 抑郁症,恐惧,压力和肠道微生物群脱不开的关系
  15. 【Python】模拟登陆并抓取拉勾网信息(selenium+phantomjs)
  16. 怎样将多个视频快速分割成两段或者多段
  17. 无需关注微信公众号破解openwrite验证
  18. php根据当前日期判断法定节假日_PHP 判断当前日期是否是法定节假日或者休息日 (原)...
  19. CSS——移动端适配方案
  20. c语言求婚代码大全,程序员表白教程,这些代码用过的都成功了!

热门文章

  1. Ubuntu系统学习笔记(8)-常用Gedit编辑器快捷键
  2. vmware 您的主机不满足在启用hyper-v或device/credential guard
  3. python cookiejar_Python http.cookiejar模块:管理cookie
  4. 面试官问如何评价上家公司要怎么回答较好?
  5. Office Web外接程序开发流程
  6. 数据库三级模式两层映射
  7. Java知识体系总结
  8. 小猫说话叫自己阿贵 专家称可会说更多(图)
  9. html flex布局换行,flex布局换行后间隙问题
  10. wsus补丁服务器部署方法