从浏览器输入URL到页面显示,到底发生了什么?

今天我们来聊一个经典面试题:”从浏览器输入URL到页面显示,到底发生了什么?”看似简单的问题,却涵盖了计算机网络的方方面面。让我们开始这段奇妙的旅程!

一、输入阶段:不起眼的地址栏暗藏玄机

当你在地址栏输入www.baidu.com时,浏览器就开始忙了:
// 浏览器内部可能的处理逻辑class Browser {    async handleInput(url) {        // 1. URL合法性检查        if (!this.isValidURL(url)) {            return this.handleSearchInput(url);        }
        // 2. HSTS检查        if (this.hasHSTSRecord(url)) {            url = url.replace('http://', 'https://');        }
        // 3. 准备请求        await this.startRequest(url);    }}
很多浏览器会在你输入时就开始预测性地发起DNS查询,这就是为什么有时候网页打开特别快!

二、DNS解析:全球最大的翻译官

// DNS解析过程的伪代码表示async function resolveDomain(domain) {    // 1. 检查浏览器缓存    let ip = browserDNSCache.get(domain);    if (ip) return ip;
    // 2. 检查操作系统缓存    ip = await checkOSCache(domain);    if (ip) return ip;
    // 3. 检查本地hosts文件    ip = await checkHostsFile(domain);    if (ip) return ip;
    // 4. 递归DNS服务器查询    ip = await recursiveDNSQuery(domain);
    return ip;}
DNS解析流程:
浏览器缓存 → OS缓存 → hosts文件 → 本地DNS服务器 → 根DNS服务器 → 顶级域名服务器 → 权威DNS服务器

三、TCP连接:三次握手的艺术

来看看三次握手的过程:
// TCP连接建立过程的伪代码class TCPConnection { enum State { CLOSED, SYN_SENT, SYN_RECEIVED, ESTABLISHED } State state = State.CLOSED;
void connect() { // 第一次握手:客户端发送SYN sendSYN(); state = State.SYN_SENT;
// 第二次握手:服务器返回SYN+ACK onReceiveSYNACK(() => { // 第三次握手:客户端发送ACK sendACK(); state = State.ESTABLISHED; }); }}

现代浏览器都支持TCP Fast Open技术,可以在握手阶段就开始传输数据,进一步提升性能!

四、TLS握手:安全的艺术

如果是HTTPS请求,还需要进行TLS握手:
// TLS握手过程async function tlsHandshake() {    // 1. Client Hello    const clientHello = {        tls_version: 'TLS 1.3',        cipher_suites: ['TLS_AES_128_GCM_SHA256', ...],        random: generateRandom(),    };
    // 2. Server Hello + 证书    const serverResponse = await sendClientHello(clientHello);
    // 3. 验证证书    if (!verifyCertificate(serverResponse.certificate)) {        throw new Error('Certificate Invalid');    }
    // 4. 生成会话密钥    const sessionKey = generateSessionKey(        clientHello.random,        serverResponse.random    );}

五、HTTP请求:真正的通信开始

// 发送HTTP请求async sendHTTPRequest(connection) {    // 构造HTTP请求    const request = {        method: 'GET',        url: this.currentURL,        headers: {            'Host': new URL(this.currentURL).hostname,            'User - Agent': 'Mozilla / 5.0...',            'Accept': 'text / html, application/ xhtml + xml...',            'Accept - Language': 'zh - CN, zh; q = 0.9',            'Accept - Encoding': 'gzip, deflate, br',            'Connection': 'keep - alive',            'Cache -Control': 'max - age = 0'        }    };
    // 发送请求    await connection.send(request);
    // 接收响应    return await connection.receive();}

六、服务器处理:后端的较量

服务器接收到请求后的处理流程:
# Django处理流程示例class WSGIHandler:    def __call__(self, environ, start_response):        # 1. 路由解析        resolver = URLResolver(ROOT_URLCONF)        callback, callback_args = resolver.resolve(path)
        # 2. 中间件处理        for middleware in self.middleware:            response = middleware.process_request(request)            if response:                return response
        # 3. 视图处理        response = callback(request, *callback_args)
        # 4. 响应处理        for middleware in reversed(self.middleware):            response = middleware.process_response(request, response)
        return response

七、浏览器渲染:最后的艺术

// 渲染流程伪代码class Renderer {    async render(html) {        // 1. 构建DOM树        const domTree = this.parseHTML(html);
        // 2. 构建CSSOM树        const cssomTree = this.parseCSS(css);
        // 3. 合并成渲染树        const renderTree = this.constructRenderTree(domTree, cssomTree);
        // 4. 布局计算        this.layout(renderTree);
        // 5. 绘制        await this.paint(renderTree);
        // 6. 合成        this.composite();    }}

总结

让我们来总结整个过程:
输入URL → DNS解析 → TCP连接 → TLS握手 → HTTP请求 → 服务器处理 → 浏览器渲染
一个URL背后,是无数程序的精密配合。理解这个过程,不仅能让你在面试中脱颖而出,更能帮助你成为更优秀的开发者。

原创文章,作者:速盾高防cdn,如若转载,请注明出处:https://www.sudun.com/ask/205701.html

Like (0)
速盾高防cdn的头像速盾高防cdn
Previous 2024年11月13日
Next 2024年11月14日

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注