前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >在浏览器输入网址,Enter之后发生了什么?

在浏览器输入网址,Enter之后发生了什么?

作者头像
有态度的马甲
发布2024-04-26 18:46:05
1430
发布2024-04-26 18:46:05
举报
文章被收录于专栏:精益码农
在浏览器输入网址,Enter之后发生了什么?

很多八股文会给出:

  1. 1. DNS Resolution
  2. 2. Establishing a Connection
  3. 3. Sending an Http Request
  4. 4. Receiving the HTTP Response
  5. 5. Rendering the Web Page

但今天我斗胆插入第0.9步URL Parsing

URL( uniform resource locator)由四部分组成:scheme、domain、path、resource

URL Parsing做了2个事情:

  • • prase url:只有解析分离出domain,还有后续的第1步: DNS resolution
  • • url_encode

本文我主要想聊一聊url_encode

  1. 1. 为什么会有url_encode?
  2. 2. javascript encodeURI() vs encodeURIComponent()
  3. 3. 我为什么会关注到这个问题?
  4. 4. 常见的httpclient默认有做url_encode吗?

在浏览器插入https://www.baidu.com/s?wd=博客园马甲哥,Enter之前童鞋们可尝试拷贝地址栏, 粘贴到任意位置, 内容是:https://www.baidu.com/s?wd=%E5%8D%9A%E5%AE%A2%E5%9B%AD%E9%A9%AC%E7%94%B2%E5%93%A5, 这就是浏览器自动url_encode的结果, 浏览器会拿这个网址去做 dns、request行为。

1. 为什么会有url_encode?

url_encode 又叫百分号编码,为什么要有url_encode[1],看知乎。

总结下来:uri地址最初要求是以可显示、可写的 ascii 字符集, 非英文字符和其他特殊字符需要被编码。

默认按照UTF-8转化为字节流,每个字节按16进制表示,并添加%组成一个percent编码。

UTF-8 到底是什么意思?[2]

例如:汉字 “你好”

  • • UTF-8字节流打印为:-28 -67 -96 -27 -91 -67
  • • 对应的16进制表示为:E4 BD A0 E5 A5 BD
  • • URLEncode编译后为:%E4%BD%A0%E5%A5%BD

当然服务端会对应的url_decode函数,编码/解码的次数需要对应。

2. js 中的encodeURI() vs encodeURIComponent()

是js 中内置的全局函数,用于url_encode,不会对以下特殊字符编码,这也是为了确保url中原生字符的正确表达: A–Z a–z 0–9 - _ . ! ~ * ' ( ) ; / ? : @ & = + $ , #

代码语言:javascript
复制
const uri = 'https://mozilla.org/?x=шеллы';
const encoded = encodeURI(uri);
console.log(encoded);
// Expected output: "https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B"

encodeURIComponent 也是全局函数,但他的用途是对字符串做完整的url_encode, 这个函数会对上面排除的字符做编码,这个函数一般用于已知是特殊字符需要做url编码。

代码语言:javascript
复制
// Encodes characters such as ?,=,/,&,:
console.log(`?x=${encodeURIComponent('test?')}`);
// Expected output: "?x=test%3F"
3.我为什么会关注这个问题?

一般web框架会为我们自动解码,我在使用lua-resty-http客户端做反向代理请求时关注到这个问题。

nginx内置变量并提供了自定义变量的能力[3]。

  • • $request_uri full original request URI (with arguments)
  • uricurrent URI in request, normalized, The value of uri may change during request processing, e.g. when doing internal redirects, or when using index files.

一开始lua_resty_http 将 $uri(解码值)送到应用,不符合应用的预期, 我这才发现应恢复成原始编码uri[4]。

4. 常见的httpclient是否能自动url_encode?

.NET、go、lua的HttpClient(包括curl)都不会自动对 URL 进行编码。如果你的 URL 包含特殊字符或需要编码的字符,你需要自己手动进行 URL 编码。

  • • [C#] System.Net.WebUtility.UrlEncode
  • • [golang] url.QueryEscape(rawURL)
  • • [lua] ngx.escape_uri(str, 0)

本文记录了url_encode的来龙去脉;引用的知乎外链都是高赞答案,人人为我我为人人; 整理了常见httpclient url_encode的表现。

文字和图片均为原创,一家之言,欢迎留言吐槽。

引用链接

[1] 为什么要有url_encode: https://zhuanlan.zhihu.com/p/557035152?utm_id=0 [2] UTF-8 到底是什么意思?: https://zhuanlan.zhihu.com/p/137875615 [3] nginx内置变量并提供了自定义变量的能力: https://nginx.org/en/docs/http/ngx_http_core_module.html [4] 应恢复成原始编码uri: https://stackoverflow.com/questions/78225022/is-there-a-lua-equivalent-of-the-javascript-encodeuri-function

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-04-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 精益码农 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 为什么会有url_encode?
  • 2. js 中的encodeURI() vs encodeURIComponent()
  • 3.我为什么会关注这个问题?
  • 4. 常见的httpclient是否能自动url_encode?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档