浏览器输入url发生了什么

604 阅读5分钟

夜深了,静下心来码字。

本文主要从两个方面去聊,第一是网络知识(参考小满zs网络课程),第二呢,是leetcode的算法题。

小伙伴问了,我™进来看发生了什么的,你跟我聊算法搞毛线?各位老哥们先别急,我尽量以尽量简短的文字,来总结概括,让各位有一个大概的脉络,就像你爱刷短视频的样子,不搞长篇大论,只搞分支和流程。细节有待各位自己深究。

模块一 浏览器输入url之后发生了什么

1.url

http://www.demo.com/demo/demo.html

http 是协议;www.demo.com 是域名;/demo/demo.html是资源文件

2.DNS

dns是负责将ip和域名进行映射

dns查找规则:

  1. 浏览器自身dns
  2. 操作系统dns
  3. 本地hosts文件
  4. 向域名服务器发送请求

注意4的流程又分为以下:

  1. 根域名服务器
  2. 顶级域名服务器
  3. 权威域名服务器

3.DNS查找之后拿到IP

到OSI七层参考模型,3次握手建立连接(不展开细说),发送http请求,也就是应用层。

这里还有个细节,就是options请求,会发生在post请求之前。触发情况有两种:1.跨域、2.post请求的请求头Content-Type为application/json的时候也会触发,其他情况不会。

4.浏览器缓存

强缓存:后台配置两个字段,Expires和Cache-Control(Cache-Control优先级高于Expires,评论区可讨论),设置这两个字段,第二次发送请求就直接从浏览器返回,不经过服务端。缓存的资源存放在硬盘和内存两个地方。

协商缓存:通过Modified相关的字段和ETag字段来设置(ETag的优先级高于Modified相关字段,评论区可讨论)。

5.四次挥手

断开连接,拿到html页面进行渲染,这块内容比较多,又涉及到dom的回流与重绘,js的执行顺序,宏任务微任务,好又可以聊到vue里的nextTick,它作用是什么,源码又怎么实现的等又可以聊很久。

6.浏览器解析js到计算机组成原理

中间会通过各种转换(为了适配win mac linux的跨平台),最终转换为机器识别的二进制 1001010...,然后运行到cpu。硬件是基于冯诺依曼架构体系实现,有兴趣童鞋可以深入了解。


模块二 leetcode算法题

好,各位看官肯定也看累了,咱们跳出刚才的理论知识,来聊一道算法题,leetcode 468 验证IP地址。直接把题copy到这儿:

给定一个字符串 queryIP。如果是有效的 IPv4 地址,返回 "IPv4" ;如果是有效的 IPv6 地址,返回 "IPv6" ;如果不是上述类型的 IP 地址,返回 "Neither" 。

行,有AI,咱们直接出答案:

var validIPAddress = function(queryIP) {
    // Check if it's a valid IPv4 address
    if (/^(?:\d{1,3}\.){3}\d{1,3}$/.test(queryIP)) {
        let octets = queryIP.split('.');
        for (let i = 0; i < octets.length; i++) {
            let octet = parseInt(octets[i], 10);
            if (octet > 255) {
                return 'Neither';
            }
        }
        return 'IPv4';
    }

    // Check if it's a valid IPv6 address
    if (/^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$/.test(queryIP)) {
        return 'IPv6';
    }

    return 'Neither';
};

经测试,确实通过,ok各位小伙伴就兴高采烈结束了?不会吧,不会吧。你得分析它的算法怎么实现啊,不管你是用js来写,或者java来写,python来写,你总得知道这个过程吧。

一、首先,解这个算法题,你肯定得知道ipv4和ipv6的规则:

ipv4通过点进行分隔,每组数在0-255(十进制)之间,

ipv6 IPv6二进位制下为128位长度,以16位为一组,每组以冒号“:”隔开,可以分为8组,每组以4位 十六进制 方式表示。例如:2001:0db8:86a3:08d3:1319:8a2e:0370:7344 是一个合法的IPv6地址。

二、然后,咱们以第一个if判断为例,它是来验证给出的字符串是否是ipv4

1.首先它判断给出的字符串每组数是否是3位且在0-9之间

2.如果true,则进入内部,将给定的字符串按照点分隔为数组,然后对每块进行遍历,并将每一项其转为10进制,如果比255大就返回Neither,否则就返回IPv4

三、IPv6同样是通过正则进行判断,这里就不展开细说了。

那么测试的话,'192.168.0.11'是没问题的,那么'192.168.00.11',依然返回是IPv4,那么就有问题了,说明AI给出的题解是有bug的,有些判断并没有考虑到,就比如我其中有个数字,是大于两位的,但是首个数字是0,应该返回Neither,这里就并没有进行判断。有兴趣的小伙伴可以自行加上对应的判断。

总结

ok,吧啦吧啦这么多,从一个url输入到底发生了什么,竟然可以聊这么多,或许我们输入url可能只是为了想看一个视频,想听一段音乐,想看一段文字,想和某人说说话。而不是去联想这么多"没用的XP",所以为什么要让自己不快乐,因为生活总归继续(混口饭吃),用心走并不一定会越来越好,但是摆烂必定会越来越差。

我们反复打磨我们的技能去实现各种各样的功能,就像厨师炒菜,亦或工人盖房,你总得去掌握凉菜怎么做,热菜怎么做,水泥怎么和,墙面怎么砌。而不是,哇,菜真香,房真好看,而自己什么技能都不会。