首页 / 资讯中心 / 文章详情

面试题:同一个 URL,手机打开是移动端页面,电脑打开是 PC 页面,怎么实现?

面试题:同一个 URL,手机打开是移动端页面,电脑打开是 PC 页面,怎么实现? ★ FEATURED ARTICLE
一、面试题同一个 URL手机打开是移动端页面电脑打开是 PC 页面怎么实现1. 核心思路一句话主要看移动端和 PC 端的页面差异差异小用响应式布局共用一套页面差异大服务端根据 User-Agent 等请求信息识别终端再分别提供两套页面。主要矛盾不是“怎么判断设备”而是“两个端到底应该共用多少代码”。次要矛盾屏幕尺寸怎么适配是否需要不同的 HTML 结构是否需要不同的 JavaScript 逻辑是否需要分别部署首屏性能和资源体积SEO 和缓存策略二、解决方案流程图同一个 URL │ ▼ 移动端和 PC 端差异大吗 ┌──────┴──────┐ 小 大 │ │ ▼ ▼ 共用一套页面 分开提供页面 │ │ ▼ ▼ 响应式设计 服务端识别终端 │ │ ┌──────┴──────┐ ▼ │ │ User-Agent ▼ ▼ │ CSS媒体查询 流体布局 ▼ │ │ PC / Mobile │ │ │ ▼ │ ┌───┴───┐ 少量布局差异 │ ▼ ▼ 直接调整 CSS │ PC页面 移动页面 │ │ └──────┬──────┘ ▼ 共用代码较多三、方案一流体布局核心思路让页面尺寸随着视口变化通过百分比、相对单位、弹性布局等方式自动缩放和排列。例如屏幕变宽 ↓ 容器变宽 ↓ 内容跟着变宽 屏幕变窄 ↓ 容器变窄 ↓ 内容跟着变窄示例!DOCTYPEhtmlhtmllangzh-CNheadmetacharsetUTF-8/metanameviewportcontentwidthdevice-width, initial-scale1.0/style/* 页面主体宽度随视口变化 */.container{width:80%;max-width:1200px;margin:0 auto;/* * 使用 Flexbox 让内部内容具备弹性布局能力。 */display:flex;gap:20px;}.sidebar{/* * 左侧固定一个相对稳定的宽度。 */width:240px;flex-shrink:0;}.content{/* * 剩余空间全部交给内容区域。 */flex:1;min-width:0;}img{/* * 图片不能超过父容器。 */max-width:100%;height:auto;}/style/headbodydivclasscontainerasideclasssidebar左侧菜单/asidemainclasscontenth1文章标题/h1p页面内容随着容器宽度变化。/pimgsrcimage.jpgalt示例图片//main/div/body/html底层原理流体布局本质上是视口尺寸 ↓ CSS布局计算 ↓ 百分比 / vw / rem / Flexbox / Grid ↓ 重新计算元素尺寸和位置 ↓ 页面随着空间变化它解决的是“同一套页面在不同尺寸下怎么自然缩放和排列”但它不一定解决“手机和 PC 的页面结构、功能、交互完全不同怎么办”因此不能简单把“响应式设计”等同于“所有页面只需要缩放”。四、方案二CSS 媒体查询核心思路页面和组件基本共用只在不同屏幕条件下修改布局、尺寸、显示状态等样式。这是实际开发中非常常见的方案。同一份 HTML │ ▼ CSS 媒体查询 │ ┌────┴────┐ ▼ ▼ PC样式 移动端样式示例!DOCTYPEhtmlhtmllangzh-CNheadmetacharsetUTF-8/metanameviewportcontentwidthdevice-width, initial-scale1.0/style/* * 默认按照移动端设计。 */.container{display:flex;flex-direction:column;gap:16px;}.sidebar{width:100%;}.desktop-only{display:none;}/* * 当视口宽度达到 768px 时 * 切换到更适合平板/PC的布局。 */media(min-width:768px){.container{flex-direction:row;}.sidebar{width:240px;flex-shrink:0;}.desktop-only{display:block;}}/style/headbodydivclasscontainerasideclasssidebar菜单/asidemainh1商品详情/h1!-- PC端额外展示的内容 --sectionclassdesktop-onlyPC端扩展信息/sectionp商品描述/p/main/div/body/html底层原理浏览器会根据当前媒体环境判断 CSS 条件是否成立浏览器获取视口尺寸 ↓ 匹配 media 条件 ↓ 条件成立 ↓ 应用对应 CSS ↓ 重新计算样式和布局例如media(max-width:767px){/* 移动端 */}media(min-width:768px){/* PC / 平板 */}它的优势如果两端业务逻辑相同 组件结构基本相同 数据基本相同 只有布局和少量展示差异那么一套 HTML 一套 JavaScript 少量媒体查询 CSS开发和维护成本比较低。五、JavaScript 如何根据屏幕尺寸执行不同逻辑如果只是样式变化优先使用 CSS 媒体查询。如果确实存在不同屏幕尺寸需要执行不同 JavaScript 逻辑可以使用window.matchMedia()。示例// 创建一个媒体查询对象。// 判断当前视口是否属于移动端。constmediaQuerywindow.matchMedia((max-width: 767px));functionhandleViewportChange(event){if(event.matches){// 移动端逻辑console.log(当前是移动端布局);}else{// PC端逻辑console.log(当前是 PC 端布局);}}// 页面初始化时先执行一次。handleViewportChange(mediaQuery);// 当视口尺寸发生变化并导致匹配结果变化时执行。mediaQuery.addEventListener(change,handleViewportChange);六、方案三服务端识别终端分别提供页面如果移动端和 PC 端已经是两套完全不同的页面那么可以在服务端根据请求信息判断终端。最常见的信息之一就是User-Agent请求头。浏览器 │ │ 请求同一个 URL ▼ 反向代理 / Web服务器 │ │ 读取 User-Agent ▼ 判断终端类型 │ ├──────────────┐ ▼ ▼ 移动端 PC端 │ │ ▼ ▼ 移动端页面 PC页面注意User-Agent 负责提供终端识别依据服务器可以根据判断结果直接返回对应页面也可以选择重定向到另一个 URL。七、服务端直接返回不同页面例如 Node.jsimporthttpfromnode:http;constserverhttp.createServer((req,res){/* * User-Agent 是浏览器发送过来的请求头。 * * 注意 * User-Agent 只能作为终端判断依据之一 * 不能把它当成绝对可靠的“设备身份证”。 */constuserAgentreq.headers[user-agent]||;// 这里只演示最简单的移动端判断。constisMobile/Android|iPhone|iPad|Mobile/i.test(userAgent);res.setHeader(Content-Type,text/html; charsetutf-8);if(isMobile){// 移动端直接返回移动端 HTML。res.end(!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title移动端页面/title /head body h1这是移动端页面/h1 /body /html);}else{// PC端直接返回 PC HTML。res.end(!DOCTYPE html html langzh-CN head meta charsetUTF-8 titlePC端页面/title /head body h1这是 PC 端页面/h1 /body /html);}});server.listen(3000);这种情况下https://example.com/始终是同一个 URL。但是手机请求 ↓ 服务器识别 User-Agent ↓ 返回移动端 HTML PC请求 ↓ 服务器识别 User-Agent ↓ 返回 PC HTMLURL 可以完全不变。八、如果需要跳转到移动端 URL可以使用 302例如PC https://example.com/ 移动端 https://m.example.com/服务器判断移动端后HTTP/1.1 302 Found Location: https://m.example.com/浏览器收到以后再请求https://m.example.com/流程手机 │ │ GET / ▼ 服务器 │ │ 判断 User-Agent ▼ 移动端 │ │ 302 Location ▼ 浏览器 │ │ GET https://m.example.com/ ▼ 移动端服务器 │ ▼ 移动端页面301 和 302 的区别301 → 永久重定向 302 → 临时重定向302 是临时重定向301 是永久重定向。如果只是根据当前设备临时把用户引导到另一个地址通常不会因为“设备不同”就直接把它理解成永久迁移。九、三种方案到底怎么选方案页面关系核心特点适用场景流体布局基本同一套页面尺寸随空间变化页面结构非常简单CSS 媒体查询高度复用不同尺寸应用不同 CSS两端差异较小服务端识别终端可以完全不同服务端决定返回哪套页面两端差异较大独立部署两套应用独立开发、部署、维护两端业务和交互差异非常大十、真正应该怎么判断不要简单问“页面复杂不复杂”更应该问“移动端和 PC 端的差异有多大”例如场景一电商详情页PC 商品图片 商品信息 推荐商品 移动端 商品图片 商品信息 推荐商品主要只是布局变化 字号变化 间距变化 部分内容隐藏这种情况下适合响应式布局 CSS 媒体查询场景二管理后台PC左侧导航 顶部导航 多列数据表格 复杂筛选移动端底部导航 卡片列表 抽屉筛选 完全不同的交互如果强行使用一套 DOM大量 if 判断 大量 CSS 覆盖 大量移动端/PC端分支最终容易变成一套代码 ↓ 大量条件判断 ↓ 维护困难 ↓ 构建产物也可能包含两端不需要的代码这时候可以考虑PC端应用 移动端应用 公共组件 / 公共业务模块 服务端路由或网关进行终端分流十一、一个更合理的现代工程方案实际项目不要简单理解成“移动端和 PC 端不同就复制两份代码。”更合理的是同一个业务 │ ┌────────────┴────────────┐ ▼ ▼ PC端应用 移动端应用 │ │ └────────────┬────────────┘ ▼ 公共业务层 │ ┌────────┼────────┐ ▼ ▼ ▼ API层 工具函数 公共组件这样可以做到页面层 → 两端独立 业务逻辑 → 尽可能复用 接口层 → 复用 工具函数 → 复用 设计 Token → 尽可能复用 基础组件 → 根据实际情况复用这样比“所有东西都共用”或者“所有东西全部复制”都更容易长期维护。十二、边界场景1. User-Agent 不是绝对可靠不能简单理解成User-Agent 真实设备因为浏览器可以修改 User-Agent爬虫可以伪造 User-Agent平板设备判断存在复杂情况新设备和新浏览器可能出现新的标识所以服务端设备识别应该设计成User-Agent 设备能力 业务规则而不是依赖某几个字符串永久判断。2. 不要为了隐藏几个元素就拆成两套页面例如PC 多一个搜索框 移动端少一个搜索框没必要直接拆成PC项目 移动端项目这种场景通常media(...)就足够了。3. 不要用 JavaScript 代替 CSS 做纯样式响应式例如if(window.innerWidth768){element.style.displaynone;}如果只是控制样式这通常不如media(max-width:767px){.element{display:none;}}因为样式问题 → CSS解决 业务逻辑问题 → JavaScript解决这是比较重要的职责划分。十三、底层原理总结这道题实际上涉及三个层次第一层CSS布局层 ↓ 视口变化 ↓ 媒体查询 / Flexbox / Grid / 相对单位 ↓ 调整页面布局 第二层浏览器逻辑层 ↓ window.matchMedia() ↓ JavaScript感知媒体条件变化 ↓ 执行不同业务逻辑 第三层服务端分流层 ↓ HTTP请求 ↓ 读取 User-Agent 等请求信息 ↓ 识别终端 ↓ 返回不同HTML 或者 返回重定向响应因此要记住CSS 媒体查询解决的是“同一页面怎么适配不同屏幕”window.matchMedia()解决的是“JavaScript 是否需要感知媒体条件”服务端分流解决的是“不同终端是否应该拿到不同的页面”。十四、结构化逻辑思维遇到这道题可以按照下面的顺序回答① 先确认需求 ↓ 同一个 URL ↓ 手机和 PC 是否需要不同页面 ② 看差异程度 ↓ 差异小 → 共用页面 → 响应式布局 → CSS媒体查询 差异大 → 页面结构和交互都不同 → 服务端分流 → 分别提供 PC / 移动端页面 ③ 再看 JavaScript ↓ 只是样式变化 → CSS 需要不同 JS 逻辑 → window.matchMedia() ④ 再看部署方式 ↓ 差异较大 → 可以独立构建、部署两端应用 ⑤ 最后考虑工程问题 ↓ 公共代码复用 缓存 SEO 首屏性能 资源体积 维护成本十五、满分答案同一个 URL 实现 PC 和移动端不同页面核心看两端差异有多大。如果两端结构和业务基本一致只是布局、尺寸、部分内容展示不同我会采用响应式设计主要用 CSS 媒体查询必要时用window.matchMedia()让 JavaScript 感知屏幕条件。如果两端页面结构、交互甚至业务逻辑差异很大我会考虑 PC 和移动端分别开发、构建和部署然后由服务端或反向代理根据请求中的User-Agent等信息进行终端识别直接返回对应页面如果采用不同 URL也可以通过 302 临时重定向到移动端地址。所以这道题真正的判断标准不是页面复杂不复杂而是 PC 和移动端的差异大小差异小就尽量复用差异大就适当拆分同时把公共业务和基础能力抽出来复用。
阅读完成 · 觉得有帮助?
咨询建站