手写 URL 解析器,面试官到底想考什么?

前言

最近一直在看一些面经,发现大部分面试官问八股提到URL的话,十有八九就是问从URL到页面渲染,但是我看到一个比较有意思的手写题:解析URL。对于没见过的面试题,我都是非常感兴趣的,下面来分享并说说我是怎么做的。

有关从URL到页面渲染的请看我的文章:网页都知道要双向握手才加载!从 URL 到页面渲染,单向喜欢连 DNS 都解析不通

一、先搞懂:URL 到底长啥样?

在动手写代码前,咱们先拆解下目标 URL 的结构,就像拆快递一样,一层一层来。后面的是我自己随便编的,我们只需输出结果,不影响:

JavaScript 复制代码
const url = 'https://www.baidu.com/order/home?user=Tom&id=123&city=上海&id=56';

它的结构可以拆成 4 部分:

  • 协议(protocol) :https ------ 告诉浏览器用什么方式传输数据
  • 主机名(hostname)www.baidu.com ------ 目标服务器的 "家门地址"
  • 路径(path) :/order/home ------ 服务器上具体的 "房间号"
  • 查询参数(query) :? 后面的所有内容 ------ 传给服务器的 "小纸条",重点是这里有重复的 id 参数,需要转成数组!

我们的目标就是把它转成规整的对象:

JavaScript 复制代码
// 期望输出的结果
const output = {
    protocol: 'https',
    hostname: 'www.baidu.com',
    path: '/order/home',
    query: {
        user: 'Tom',
        id: [123, 56], // 重复参数自动转数组
        city: '上海'
    }
}

二、动手开写!原生 JS 手写 URL 解析器

当时我就没想那么多,可能是暴力解题用多了。这核心思路不就一个:字符串拆分(split)+ 循环组装,不用任何框架,纯原生 JS 不就能搞定吗?

JavaScript 复制代码
// 待解析的URL
const url = 'https://www.baidu.com/order/home?user=Tom&id=123&city=上海&id=56';

// URL解析函数
function urlParser(url) {
    // 1. 拆分协议:以"://"为分割符,前面就是协议https
    const protocalArr = url.split('://');
    const protocol = protocalArr[0];

    // 2. 拆分主机名:协议后面的字符串,以"/"分割,第一段就是主机名
    const hostname = protocalArr[1].split('/')[0];

    // 3. 拆分路径:主机名后面、?前面的部分就是路径
    const path = protocalArr[1].split(hostname)[1].split('?')[0];

    // 4. 拆分查询参数:?后面的内容用&分割,得到每一个参数项
    const queryArr = protocalArr[1].split(hostname)[1].split('?')[1].split('&');
    const queryObj = {}; // 用来存放最终的参数对象

    // 循环处理每一个参数
    queryArr.forEach(item => {
        // 每个参数用=分割,左边是key,右边是value
        const [key, value] = item.split('=');
        
        // 重点:处理重复参数(比如id出现两次)
        if (queryObj[key]) {
            // 如果已经是数组,直接push新值
            if (Array.isArray(queryObj[key])) {
                queryObj[key].push(value);
            } else {
                // 如果不是数组,转成数组再存新值
                queryObj[key] = [queryObj[key], value];
            }
        } else {
            // 无重复,直接存原值
            queryObj[key] = value;
        }
    })
    
    // 返回最终解析好的对象
    return {
        protocol,
        hostname,
        path: path,
        query: queryObj
    }
}

// 调用函数,打印结果
console.log(urlParser(url));

结语

一道很简单的手写题,无非就是麻烦一点。能出这道题我觉得大概也是想考察这个逻辑思维的能力,好了,今天的分享就到这!

相关推荐
智购科技自动售货机厂家17 分钟前
2026自动售货机AI视觉识别优化:从YOLOv11n模型量化到RKNN部署的端侧推理工程实践~YH
javascript·人工智能·yolo·机器学习·计算机视觉·目标跟踪·perl
计算机魔术师19 分钟前
AI为拿高分不惜入侵网站:22个模型作弊审计,真相让人背脊发凉
前端
晓说前端20 分钟前
TypeScript 核心语法应用 —— Vue 3 中的使用(下)
前端·javascript·typescript·类型系统
zhangminghuan30 分钟前
微信小程序开发核心知识点全景解析(前端必备硬核基础)
前端·微信小程序·小程序
boooooooom44 分钟前
尝尝咸淡:从朴素 RAG 到 Graph RAG——一个烹饪问答系统的三层检索升级之路
前端·后端·llm
cindershade1 小时前
让每条前端异常都能回答:该由谁修、为什么现在修
前端
bitbrowser1 小时前
Telegram提示尝试次数过多,换网络和重装有用吗
前端
研☆香1 小时前
前端简单的的变量声明
前端
赵大仁1 小时前
Next.js AI Route Handler 工程化:超时、流式与鉴权
前端·ai·鉴权·next.js·工程化
yuhaiqiang2 小时前
从这两件事就能看出 vibecoding 距离专业作品差距有多大?AI 能抹平技术,但抹不平品味 !
前端·后端·程序员