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

本文主要讲解关于在浏览器输入网址,Enter之后发生了什么?相关内容,让我们来一起学习下吧!

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

很多八股文会给出:

  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

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

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,看知乎。

URL encoding converts characters into a format that can be transmitted over the Internet.

URLs can only be sent over the Internet using the ASCII character-set.

Since URLs often contain characters outside the ASCII set, the URL has to be converted into a valid ASCII format.

URL encoding replaces unsafe ASCII characters with a "%" followed by two hexadecimal digits.
URLs cannot contain spaces. URL encoding normally replaces a space with a plus (+) sign or with %20.

默认按照UTF-8编码, 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函数, 编码/解码的次数需要对应。

--

各种语言都提供 urlencode、decode的支持,这种支持不仅是url,也有对字符串的支持。

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反代时就要注意这个问题。

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

直连应用的时候,浏览器的发出的是url_encode请求;

接入openresty网关时, 内部使用的$uri 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.

延伸

https://dev.to/sidthesloth92/understanding-html-form-encoding-url-encoded-and-multipart-forms-3lpa

form表单提交的时候,默认是 application/x-www-form-urlencoded 编码格式

<form action="/urlencoded?firstname=sid&lastname=sloth" method="POST" enctype="application/x-www-form-urlencoded">
    <input type="text" name="username" value="sidthesloth"/>
    <input type="text" name="password" value="slothsecret"/>
    <input type="submit" value="Submit" />
</form>

会产生 username=sidthesloth&password=slothsecret 编码值。

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) https://stackoverflow.com/questions/78225022/is-there-a-lua-equivalent-of-the-javascript-encodeuri-function

以上就是关于在浏览器输入网址,Enter之后发生了什么?相关的全部内容,希望对你有帮助。欢迎持续关注程序员导航网,学习愉快哦!

版权声明:cnblogshot 发表于 2024-04-25 0:25:34。
转载请注明:在浏览器输入网址,Enter之后发生了什么? | 程序员导航网

暂无评论

暂无评论...