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

enter · 浏览次数 : 0

小编点评

**URL_encode的作用:** `url_encode()` 函数用于将字符串转换为 URL 编码格式。它用於處理包含特殊字符或需要编码的字符的 URL。 **url_encode 的工作原理:** 1. `url_encode()` 将字符串转换为字节流。 2.字节流被格式化为一个 percent encoded string。 3. percent encoded string 被格式化为 URL 编码格式。 **js 中的 encodeURI() 和 encodeURIComponent() 函数:** `encodeURI()` 是一个全局函数,用于对字符串进行 URL 编码。它不会处理特殊字符。 `encodeURIComponent()` 是另一个全局函数,用于对字符串进行 URL 编码,并保留所有特殊字符。 **为什么要使用 url_encode?** 在使用 `encodeURI()` 或 `encodeURIComponent()` 对字符串进行编码时,可能需要保留所有特殊字符。`url_encode()` 则提供了更安全的编码方法,因为它使用 percent encoded string 格式。 **常见的 HttpClient 的自动编码:** 大多数 web 框架会为我们自动解码字符串,因此在直接处理 HTTP 请求时,我们可以在忽略 `url_encode()`。 **特殊情况:** 在使用 `encodeURI()` 或 `encodeURIComponent()` 对字符串进行编码时,应该注意以下特殊字符: * `?` * `=` * `&` * `:` * `;` * `/` * `?` * `:` **总结:** `url_encode()` 是一个用于处理包含特殊字符或需要编码的字符的字符串的函数。`encodeURI()` 是一个全局函数,用于对字符串进行 URL 编码,而 `encodeURIComponent()` 是一个全局函数,用于对字符串进行 URL 编码,并保留所有特殊字符。

正文

很多八股文会给出:

  1. DNS Resolution
  2. Establishing a Connection
  3. Sending an Http Request
  4. Receiving the HTTP Response
  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. 为什么会有url_encode?
  2. javascript encodeURI() vs encodeURIComponent()
  3. 我为什么会想到这个问题?
  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,看知乎。

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

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

UTF-8 到底是什么意思?

例如:汉字 “你好”

  • 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()

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

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编码。

// Encodes characters such as ?,=,/,&,:
console.log(`?x=${encodeURIComponent('test?')}`);
// Expected output: "?x=test%3F"

3.我为什么会关注这个问题?

一般web框架会为我们自动解码,所以我们在直接处理http请求时可以忽略该问题。

但是在自行使用 httpclient反代时就要注意这个问题。

nginx内置变量并提供了自定义变量的能力

  • $request_uri
    full original request URI (with arguments)
  • $uri
    current 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客户端做反向代理请求时遇到了这个问题, 一开始lua_resty_http 将 $uri(解码值)送到应用,不符合应用的预期, 应恢复成原始编码uri

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)

与在浏览器输入网址,Enter之后发生了什么?相似的内容:

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

很多八股文会给出: DNS Resolution Establishing a Connection Sending an Http Request Receiving the HTTP Response Rendering the Web Page 但今天我斗胆插入第0.9步URL Parsing

鸿蒙HarmonyOS实战-Web组件(页面跳转和浏览记录)

前言 页面跳转是指在浏览器中从当前页面跳转到另一个页面的操作。可以通过点击链接、输入网址、提交表单等方式实现页面跳转。 浏览记录是指记录用户在浏览器中浏览过的页面的历史记录。当用户跳转到一个新页面时,该页面会被加入浏览记录中,用户可以通过浏览器的后退按钮或者浏览历史列表来查看和访问之前浏览过的页

如何安全地访问互联网

当你深夜在浏览器中输入 www.baidu.com 时有没有想过,除了月黑风高的夜和本机的浏览记录,还有谁知道你访问了它呢?要搞清楚这件事,首先我们要了解一下访问网站时,这其中发生了什么。 如果你在 10 年之前访问网站,大概率会在浏览器的地址栏中看到这样的网址 http://www.baidu.c

从浏览器输入域名开始分析DNS解析过程

摘要:DNS(Domain Name System)是域名系统的英文缩写,是一种组织成域层次结构的计算机和网络服务命名系统,用于 TCP/IP 网络。 本文分享自华为云社区《DNS那些事——从浏览器输入域名开始分析DNS解析过程》,作者: 砖业洋__ 。 我们就从在浏览器输入域名开始分析。 1. D

typora下载安装以及notepad++下载安装

notepad++下载安装 找到浏览器输入:notepad或者 https://notepad-plus-plus.org/downloads/ 官网下载即可使用 如果官网崩了,可以在微信公众号:A软件安装管家,找到安装notepad++,下载安装即可。 typora下载安装 找到浏览器输入:typ

[转帖]chrome 查看已经保存的密码

方法/步骤 1 点击浏览器工具栏右上角的三个竖点的菜单图标 2 在弹出来的菜单列表中点击打开“设置” 3 在设置界面点击左侧的“自动填充” 4 接着在右侧找到“已保存的密码”,在其下方找到需要查看的网站密码 5 点击密码后面的眼睛的图标 6 在弹出的窗口中输入电脑的登录密码,点击下方的“确定”即可查

[转帖]Fiddler抓取Chrome浏览器访问baiud.com报NET::ERR_CERT_COMMON_NAME_INVALID

错误现象 解决方法: 1、Chrome浏览器地址栏中输:chrome://net-internals/#hsts 2、在Query HSTS/PKP domain处搜索www.baidu.com网站, [什么是HSTS呢?它的作用是什么?]点击了解详情(https://blog.csdn.net/q

Selenium 自动化浏览器,解决懒加载的网页获取问题

Selenium 自动化浏览器,解决懒加载的网页获取问题。可以用于爬虫这些 在使用 Selenium WebDriver 进行自动化测试时,可以通过设置日志级别来控制输出的日志信息。在 C# 中,可以通过以下方式来禁用 Selenium WebDriver 输出的日志信息: 导入 OpenQA.Se

vCenter报错:Log Disk Exhaustion on 10

vCenter报错:Log Disk Exhaustion on 10 1、问题现象: 巡检时发现 vCenter Server 中,错误显示为:Log Disk Exhaustion on 10(字面意思是日志磁盘耗尽),VC版本 6.7 在浏览器输入https://appliance-IP-ad

原生CSS嵌套简介

> 嵌套是使用Sass等CSS预处理器的核心原因之一。现在,该功能已经以类似的语法出现在标准浏览器CSS中。你能否在构建系统时放弃对预处理器的依赖? CSS嵌套可以节省输入时间,并使语法更易于阅读和维护。迄今为止,你必须像这样键入完整的选择器路径: ```css .parent1 .child1,