简介:一套以必要APP为原型的高仿H5商城纯前端静态页面合集,适合前端学习者、移动端页面开发初学者,以及需要快速搭建手机商城Demo的开发者。整套资源覆盖个人中心、商家展示、商品分类、商品详情、购物车、订单列表、登录注册、添加收货地址、余额提现等34个核心页面,共133个文件,压缩包仅2.02MB,结构清晰便于按模块查找。文件组成以72个png图片、34个html页面为主,另有11个js脚本、3个css样式表及少量字体文件;js和css采用简洁手写代码,部分交互借助jQuery插件实现,易于阅读理解并二次改动。资源包已有1226人下载学习,对于希望梳理移动商城页面组织、表单交互与整体业务逻辑的开发者,可直接参考这些静态页面完成原型演示,登录注册、订单流程、收货地址管理等场景能有效降低从零搭建的时间成本。虽然原始项目已改版,但核心页面架构与交互思路仍具实用参考价值。
1. 纯前端 H5 商城:解压就能跑的移动端商城模板
这份 H5商城.zip 解压出来,是一套不需要后端、不需要数据库、浏览器打开就能完整浏览的手机端商城静态页面。它把首页、分类、商品列表、详情页、购物车用 HTML、CSS 加原生 JavaScript 写在前端文件里,数据来自内置 mock JSON。
适合三类人:刚接触移动端开发、想看完整商城页面怎么拼起来的新手;要快速出高保真原型做演示的产品或设计师;接了活动页或外包单、想找干净模板改的开发者。它不是能直接收钱的完整电商系统,没有支付、没有后台、没有订单管理,但商城前台闭环是完整的。
每行代码都能完全掌控,不会被框架黑匣子挡住。下面按结构拆解、本地运行、改造对接、踩坑排查、上线前验证的顺序,把这份资源从 zip 到交付完整过一遍。
2. 拆开 zip 看结构:目录分工、页面模块与 mock 数据组织
解压之后第一步不是双击 index.html,而是先把目录看明白。纯前端商城项目的目录结构直接决定后面改东西的成本,拿到手我一般会先列一遍文件树,搞清楚哪些是页面、哪些是公共资源、哪些是数据文件。这套 H5商城.zip 解压后的布局,按常见静态商城模板来分,是页面、样式、脚本、图片四段式。
2.1 页面文件怎么分工:多页结构比单页更适合静态商城
这套模板走的是多页结构,index.html 负责首页,list.html 负责分类列表,detail.html 负责详情,cart.html 负责购物车,公共的 css 和 js 单独抽出来。多页结构在纯静态项目里的优势很明显:每个页面职责单一,改首页不影响购物车;页面之间只通过 URL 参数传 id,不需要维护复杂的状态管理;新手也能一眼看懂每个文件的用途。相比之下单页应用要引入路由和状态管理,对这个体量的模板来说是杀鸡用牛刀。
H5商城/ ├── index.html # 首页:banner、分类入口、推荐商品 ├── list.html # 分类商品列表 ├── detail.html # 商品详情 ├── cart.html # 购物车 ├── css/ │ ├── common.css # 公共样式:reset、按钮、底部tab │ └── index.css # 首页专属样式 ├── js/ │ ├── data.js # mock 商品数据 │ ├── common.js # 公共方法:渲染、格式化、请求 │ └── cart.js # 购物车逻辑 └── images/ # 图标、banner、商品图这是整套资源的骨架。list.html 按 category 过滤商品,detail.html 根据 URL 参数拿到商品 id 再渲染,cart.html 负责增删改和金额计算。js 目录里 data.js 是数据源头,common.js 是公共方法,cart.js 处理购物车。这个分法的好处在于:替换商品只动 data.js,新增页面只需要加一个 html 和对应的 css、js,完全不碰其他文件。
每个页面的内部结构也高度统一,从上到下是头部(搜索框或返回按钮)、内容区、底部 tab 栏三部分。底部 tab 是商城页面的共性,四个页面引用同一套结构,只是当前选中态不同,CSS 里用 .active 类控制高亮。如果你打算在模板基础上加页面,先复制一个现有页面的骨架,再改内容区,比从零写省事得多。
2.2 mock 数据和渲染逻辑:前端页面的假后台
纯静态页面没有后端,商品数据要么直接写死在 HTML 里,要么写在一个 data.js 里由 JavaScript 动态渲染。这套资源走的是后者,data.js 里是一个数组,每个元素就是一个商品对象:
// js/data.js var goodsList = [ { id: 1001, name: "简约帆布包", price: 39.9, originalPrice: 59.9, image: "images/goods/1001.jpg", category: "包袋", stock: 120, sales: 356 }, { id: 1002, name: "陶瓷马克杯", price: 25.0, originalPrice: 35.0, image: "images/goods/1002.jpg", category: "家居", stock: 80, sales: 201 } ];这个结构里,id 是唯一主键,页面跳转靠它传参;price 是现价,originalPrice 用来做划线价对比;image 是相对路径,基准是 index.html 所在目录;category 字段承担分类筛选,list.html 顶部分类入口就靠它过滤;stock 和 sales 是给前端展示库存和销量的,纯展示,没有真实校验能力。改数据时最容易出的问题就是 id 重复或图片路径写错,这两点后面单独讲。
渲染逻辑也很直白。商品列表的常见做法是把 HTML 骨架写在模板字符串里,遍历数组拼出来,最后一次性写入容器:
// js/common.js function renderGoods(list, containerId) { var container = document.getElementById(containerId); var html = ""; for (var i = 0; i < list.length; i++) { var g = list[i]; html += '<a class="goods-item" href="detail.html?id=' + g.id + '">' + '<img src="' + g.image + '" alt="' + g.name + '">' + '<div class="goods-name">' + g.name + '</div>' + '<div class="goods-price">¥' + g.price + '</div>' + '</a>'; } container.innerHTML = html; }两个参数值得注意:list 是数据源,containerId 是渲染目标的容器 id。href 里 detail.html?id=1001 是页面间传参的关键,详情页拿到参数后再从 goodsList 里查对象。innerHTML 拼接在几十条数据时没有任何问题,如果商品上千条,建议改成数组 push 后 join 一次性赋值,或者用 DocumentFragment,避免循环里多次触发布局重排。
详情页的渲染是这套数据流的下半段,逻辑是解析 URL 参数、匹配商品对象、回填页面:
// detail.html 里的参数解析与商品匹配 var query = location.search.substring(1); // 去掉问号,得到 id=1001 var pairs = query.split("&"); var params = {}; for (var i = 0; i < pairs.length; i++) { var kv = pairs[i].split("="); params[kv[0]] = decodeURIComponent(kv[1] || ""); } var goods = null; var currentId = parseInt(params.id, 10); for (var j = 0; j < goodsList.length; j++) { if (goodsList[j].id === currentId) { goods = goodsList[j]; break; } }参数解析这段用 substring(1) 去掉问号,再用 split 拆成键值对。decodeURIComponent 是为了处理中文参数,比如搜索关键词。匹配用 id 全等比较,parseInt 是为了防止 id 从 URL 里带出字符串类型导致比较失败。匹配到 goods 之后,剩下的工作就是把 goods.name、goods.price、goods.image 回填到页面对应的 DOM 节点,注意这段脚本要放在 DOM 结构之后,或者包在 DOMContentLoaded 里。
购物车数据不走 mock,走 localStorage。商品数据是静态的、只读的;购物车是用户行为产生的动态数据,必须落在本地。记住这个分工:商品数据静态化、用户数据本地化,这是纯前端商城能跑通的核心。
3. 跑起来:本地起服务、手机真机访问与微信浏览器适配
解压之后直接双击 index.html 能打开,但很快会碰到两个问题:某些浏览器对本地 file 协议下的 fetch 有限制,而且手机上看不到效果。所以正规做法是先起一个本地静态服务。这一步没有技术难点,但选择哪条路直接决定你后面调试的效率。
3.1 三种起服务的方式:从零依赖到自动刷新
我一般按场景选。纯自己看效果,用 Python 自带的 http.server,零依赖;开发期要频繁改样式,用 VS Code 的 Live Server,改完自动刷新;要给同一局域网的多台设备同时看,就把服务绑定到 0.0.0.0。这里把前两种讲透。
Windows 上装了 Python 的话,在项目根目录开命令行:
cd H5商城 python -m http.server 8080macOS 和 Linux 同样适用。跑起来后终端会输出 Serving HTTP on 0.0.0.0 port 8080,浏览器访问 http://localhost:8080/index.html 就能看到首页。端口参数可以换成 8080 之外任何未被占用的端口,我常用 8080 和 3000,避免和本地其他开发服务冲突。注意 0.0.0.0 表示监听所有网卡,局域网内其他设备也都能访问,这正好是后面真机调试的基础。
不想装 Python 的话,VS Code 装好 Live Server 插件后,在项目文件夹里右键 index.html,选 Open with Live Server,默认在 5500 端口起服务,改 css 或 js 后浏览器自动刷新。Live Server 的便利在于开发期实时反馈,但它默认绑定 127.0.0.1,手机要访问需要手动改绑定的 host,设置项里搜 liveServer.settings.host 改成 0.0.0.0 即可。
提示:千万不要用双击 index.html 的 file 协议方式做接口对接调试,fetch 和部分 ES6 写法在 file 协议下会被浏览器拦截,到时你会分不清是代码问题还是协议问题。
3.2 手机真机访问:局域网 IP 与调试流程
手机上看效果才是 H5 商城的最终场景。流程是先查到电脑的局域网 IP,然后手机和电脑连同一个 Wi-Fi,手机浏览器直接访问 IP 加端口。
ipconfig # Windows 下找 IPv4 地址,一般是 192.168.x.x ifconfig # macOS / Linux 下找 inet 地址查到 IP 后,手机浏览器访问 http://192.168.x.x:8080/index.html。如果打不开,按优先级排查三件事。第一,防火墙是否放行了端口,Windows 首次跑 python -m http.server 会弹防火墙授权,要点「允许访问」;第二,手机和电脑是否真的在同一网段,一个连 5G Wi-Fi 一个连有线网络,肯定不通,可以用 ping 验证;第三,服务是否真的绑定了所有网卡,如果服务只监听 127.0.0.1,局域网设备必然访问不到。
真机调试时看不到 console 输出是个麻烦,常见做法是在页面里临时引入 vConsole 的 CDN 脚本,手机微信里打开页面就会出现一个悬浮调试按钮,console 日志、网络请求一目了然。调试完记得移除,不然会在正式页面露出调试按钮。另外电脑上可以先开 Chrome 的设备模拟模式,把视口切成 iPhone 尺寸,解决大部分布局问题;但触摸事件、微信内置浏览器的表现是模拟器给不了的,关键流程加购、改数量、提交订单必须让手机实测一遍。我给自己的标准是:电脑上过一遍视觉,手机上过一遍完整路径。
3.3 微信内置浏览器与视口参数
H5 商城大概率是在微信里被打开的。微信内置浏览器基于 X5 / Chromium 内核,常见语法都没问题,但有两个点必须在 head 里提前声明。最基础的是 viewport:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">width=device-width 让页面宽度等于设备宽度,initial-scale=1.0 控制初始缩放比,user-scalable=no 禁止双指缩放。商城这类交互页面通常禁掉缩放,避免用户误操作后布局错乱。这里提一个取舍:禁缩放会影响部分视力障碍用户,内容型页面不建议这么写,但商城页以交互一致性优先,这个选择要心里有数。
微信内置浏览器还有一个特点:缓存非常顽固。改完代码后,微信里反复刷新看到的可能还是旧版,这不是代码问题。开发期最快的解决方法是给静态资源 URL 加版本参数,比如 index.css?v=20250101,让微信把它当成新资源拉取。这个方法到第 5 章讲缓存问题时还要再提一次。
4. 改造成你自己的商城:商品替换、接口对接与购物车持久化
跑通之后就是改造。这一章讲三个核心改动:换商品数据、接真实接口、把购物车从内存升级成持久化。这三件事做完,这套模板就从演示品变成了可以交给业务方填数据的半成品。
4.1 商品数据替换:JSON 字段、图片路径与管理习惯
换自己的商品,最直接是改 data.js 里的 goodsList。要点有三个:id 不要重复,保持自增;图片路径用相对路径,图片文件放到 images/goods 目录下;价格字段用数字,不要写字符串 "39.9",否则后面做价格汇总时可能出现字符串拼接的隐藏 bug。
// 改 data.js 时的建议结构 var goodsList = [ { id: 20101, name: "夏季纯棉T恤", price: 59.9, originalPrice: 99.0, image: "images/goods/t-shirt.jpg", category: "服饰", stock: 200, sales: 1200 } ];商品多了之后,我一般建议把 data.js 拆成独立 JSON 文件,用 fetch 加载。把数据从代码里剥出来有个实际好处:运营改价不用碰逻辑代码,只改 JSON。fetch 加载 JSON 的方式如下:
// js/common.js 中按需加载商品数据 fetch("data/goods.json") .then(function(res) { return res.json(); }) .then(function(data) { renderGoods(data.list, "goodsList"); }) .catch(function(err) { console.error("商品数据加载失败:", err); });注意一个前提,fetch 在 file:// 协议下会被浏览器拦截,所以用这种方式时必须走第 3 章的本地服务套路。如果坚持双击打开 html,就把数据继续留在 data.js 里用 script 标签引入,这是兼容性最好的方式,没有之一。
4.2 mock 数据替换成真实接口:fetch 封装与降级策略
真实项目中后端接口不是随时就绪的,常见做法是先对着 mock 数据结构开发,后端好了再把请求地址换掉。为了减少改动,我会在 common.js 里做一个极简请求封装:
// js/common.js 极简请求封装 function request(url, params) { var query = ""; if (params) { query = "?" + Object.keys(params) .map(function(k) { return k + "=" + encodeURIComponent(params[k]); }) .join("&"); } return fetch(url + query) .then(function(res) { return res.json(); }) .catch(function(err) { console.error("请求失败:", url, err); return null; // 返回 null 方便调用方判断 }); }这个封装做的事情很简单:拼查询串、发 fetch、统一捕获异常。调用的时候传 baseUrl 和参数,后端接口就绪后只改 baseUrl 一行。降级策略是开发期常用的做法:如果 request 返回 null 或者接口未开通,就回退到 data.js 的 mock 数据渲染,页面不会白屏。这个先 mock 后接口的过渡方式,能避免前后端联调时互相等待。
接真实接口时有两个参数细节值得注意。一是接口返回的字段名可能和 mock 对不上,常见做法是在封装层做一个字段映射,而不是改所有页面;二是价格字段的类型,后端返回的可能是分(整数),前端要除以 100 再展示,这种单位 bug 在商城项目里非常常见。
// 接口字段映射示例:后端字段与页面字段不一致时 var fieldMap = { title: "name", cover: "image", currentPrice: "price" }; function mapGoods(raw) { var item = {}; item.name = raw[fieldMap.title]; item.image = raw[fieldMap.cover]; item.price = raw.currentPrice / 100; // 后端返回分,前端转元 return item; }字段映射的核心是把「后端给的原始数据结构」和「前端页面的消费结构」解耦。后端改了字段名,只动 fieldMap,页面渲染代码一行不用碰。单位换算单独写成一个除法,是因为分转元这个逻辑太容易漏,我见过不止一次线上价格大了 100 倍的翻车现场。
4.3 购物车持久化:localStorage 的存取、数量同步与清空时机
购物车是纯前端商城最像动态功能的部分。没有后端的情况下,购物车数据必须落在本地,否则刷新就丢。核心是三个操作:读、写、清。
// js/cart.js 购物车持久化 var CART_KEY = "h5_mall_cart"; function getCart() { var cart = localStorage.getItem(CART_KEY); return cart ? JSON.parse(cart) : []; } function saveCart(cart) { localStorage.setItem(CART_KEY, JSON.stringify(cart)); } function addToCart(goodsId, count) { var cart = getCart(); var found = false; for (var i = 0; i < cart.length; i++) { if (cart[i].goodsId === goodsId) { cart[i].count += count; found = true; break; } } if (!found) { cart.push({ goodsId: goodsId, count: count }); } saveCart(cart); renderCartBadge(cart); }这里有几个容易踩的点。第一个是存进去之前必须 JSON.stringify,取出来必须 JSON.parse,否则 localStorage 里存的是 "[object Object]"。第二个是购物车数组里只存 goodsId 和 count,商品名称、价格不要存进去,因为价格会变,商品信息每次渲染时从 goodsList 里按 id 查,这样改价后购物车自动更新。第三个是清空时机,订单提交成功后要调 clearCart,但纯前端没有真实支付,所以下单按钮通常只是跳到一个订单确认静态页,真正的清空在确认页的模拟提交动作里执行,这个逻辑要跟产品确认清楚,避免演示时出现下单后购物车还满着的尴尬。
购物车角标的数量同步也是常见问题。首页、列表、详情页的底部 tab 上有个购物车数字,它在每次页面加载时读 localStorage 刷新,而不是跨页面实时同步。所以从详情页加购后跳回首页,首页要重新读一次,这是多页结构的天然限制,也是新手最容易漏掉的细节。
// 购物车角标渲染 function renderCartBadge(cart) { var total = 0; for (var i = 0; i < cart.length; i++) { total += cart[i].count; } var badge = document.getElementById("cartBadge"); if (badge) { badge.style.display = total > 0 ? "block" : "none"; badge.innerHTML = total > 99 ? "99+" : String(total); } }角标渲染有个约定俗成的显示规则:超过 99 显示 99+,防止三位数把 tab 栏撑破;数量为 0 时整个角标隐藏,而不是显示 0。这个细节虽然小,但直接影响演示时的第一印象,值得按这个标准写。
5. 踩坑排查:静态商城从开发到预览的五个高发问题
下面这五条是我在静态商城项目里遇到频率最高的坑,每条按「现象 → 原因 → 解决」来写。单独看都简单,但组合起来足以耗掉一个下午,可以说是血泪经验。
5.1 图片全部裂开:相对路径与目录层级对不上
现象:页面结构正常、文字正常,但所有商品图都显示为裂图占位符。
原因:data.js 里写的图片路径是 images/goods/1001.jpg,但实际文件放在 img/ 目录下;或者页面从 list.html 打开时的相对路径基准是 list.html 所在目录,如果页面在子目录里,路径就要写成 ../images/...。裂图的本质是路径计算错误,而路径计算错误多数来自目录结构调整后没同步改数据。
解决:以 index.html 所在目录为基准统一所有图片路径,并做一个全项目搜索,确认 images 目录下每个文件名和 data.js 里的引用完全一致。Windows 下尤其注意文件名大小写,Pic.jpg 和 pic.jpg 在本地 Windows 上可能都能打开,部署到 Linux 服务器就只认一个,这种上线才暴露的问题最难查。我现在的习惯是图片引用一律小写文件名,从源头规避。
5.2 点击商品没反应:事件绑定与动态渲染的顺序问题
现象:首页滚动到的动态商品点击跳不到详情页,但首屏静态写死的商品可以跳。
原因:事件绑定发生在动态渲染之前。如果用的是 addEventListener 或 onclick 逐个绑定,那么动态渲染出来的元素根本没有绑上事件。静态商城最常见的坑就是「元素是后来生成的,绑定是提前完成的」。
解决:两种方案。一是事件委托,把 onclick 绑在容器上,通过事件冒泡判断点的是不是商品项,这是动态列表的标准做法;二是渲染完成后立即在 renderGoods 末尾重新绑定事件。我推荐事件委托,因为后续无论追加多少次列表都不用重新绑定:
document.getElementById("goodsList").addEventListener("click", function(e) { var item = e.target.closest(".goods-item"); if (item) { location.href = item.getAttribute("href"); } });注意 closest 方法在部分老旧安卓 WebView 里不支持,如果必须兼容,就改成递归找 parentNode。事件委托还有一个额外好处:容器内部新增的子元素天然生效,这正是动态渲染页面最需要的行为。
5.3 中文全是乱码:charset 声明与文件编码不一致
现象:浏览器打开后商品名、标题显示成 鈥 之类的乱码,或者部分文字变成问号。
原因:html 文件本身是 UTF-8 编码,但 head 里没有 声明,浏览器按默认编码解析;或者反过来,文件本身是 GBK 保存的,却声明了 UTF-8。Windows 下用记事本另存时容易无辜中招。
解决:统一三步。第一,所有 html、css、js 文件都用 UTF-8 无 BOM 编码保存;第二,每个 html 的 head 里第一行写上 ;第三,用 VS Code 打开文件看右下角编码标识,如果是 GBK 就点它改成 UTF-8 重新保存。这一步做完乱码基本绝迹,剩下零星问题多半出在接口返回的数据编码上,那是后端的事,另说。
5.4 安卓低版本机型布局错乱:flex 写法与图片撑破容器
现象:iPhone 上正常的商品网格,在部分安卓机上商品挤成一列,或者图片把父容器撑得奇形怪状。
原因:老安卓 WebView 对 flex 的 flex-shrink、flex-basis 支持不完整,或者图片没有设置最大宽度,被原始尺寸撑破容器。静态页商城往往在微信里跑,微信的 X5 内核版本参差不齐,布局兼容是躲不掉的活。
解决:网格布局优先用 flex-wrap 加百分比宽度,避免依赖复杂的 flex 简写。图片样式加两条铁律:img { max-width: 100%; display: block; },这能解决九成以上图片撑破布局的问题。如果用了 rem 做字号适配,注意 html 的 font-size 基准要在 DOMContentLoaded 之后再设置,否则首屏字号会突然跳变,看起来像布局抖动。
5.5 微信里打开是旧版:缓存与分享参数两个方向
现象:代码改了,电脑浏览器看是新的,手机微信打开还是旧页面;或者分享给朋友时没有标题和缩略图,只显示一个光秃秃的链接。
原因:微信内置浏览器缓存策略激进,静态资源更新后容易被命中旧缓存;分享没缩略图是因为静态页缺少微信要求的 meta 标签,微信 JS-SDK 的完整分享配置需要后端签名,纯静态页做不到完整自定义,但基础标题和缩略图可以通过 meta 标签设置。
解决:开发期用资源加版本参数的方式绕过缓存,比如 index.html?v=20250101。分享这块,先检查 index.html 的 head 里是否有 og:title、og:description、og:image 三件套,加上它们至少能保证基础展示:
<meta property="og:title" content="H5商城演示"> <meta property="og:description" content="纯前端实现的移动端商城页面"> <meta property="og:image" content="images/share.png">要提醒的是,og 标签只是静态页能做到的边界,微信里完整自定义分享卡片(带自定义图标、描述)必须接 JS-SDK,那就要有后端配合出签名。这个边界要跟需求方讲清楚,别让产品以为纯静态页能实现全套微信分享,这是我被问过最多的一句话。
6. 收尾一技:用 Chrome 开发者工具验证移动端适配与加载性能
改完、跑通、能加购之后,别急着发。交付前我用 Chrome 开发者工具做一轮固定检查,十分钟能查出大多数肉眼发现不了的问题。
第一步,打开页面按 F12,点设备模拟图标,选一个 iPhone 尺寸,重点看三样:页面有没有横向滚动条、商品网格的间距是否均匀、底部 tab 是否贴底。横向滚动条是移动端页面最常见的翻车点,通常是某个元素宽度超出了视口,用 Elements 面板逐步删除元素就能定位到肇事者。
第二步,切到 Network 面板,勾上 Disable cache,强制刷新。看两个数据:资源总大小和请求数量。纯静态商城如果首页请求超过 80 个,多半是图片没做压缩或切图太碎;单张商品图超过 200KB 就要考虑压缩,移动端弱网场景下这个差距非常明显。简化版自查表如下:
| 检查项 | 达标线 | 不达标怎么办 |
|---|---|---|
| 首页总请求数 | 小于等于 60 | 合并 CSS/JS、小图标合成雪碧图 |
| 单张图片体积 | 小于等于 200KB | 压到 70% 质量,必要时转 WebP |
| 首屏内容出现 | 小于等于 3 秒 | 非首屏图片延迟加载 |
| 横向滚动条 | 无 | 检查溢出元素宽度 |
| 字体大小 | 不小于 12px | 调整 rem 基准 |
第三步,用 Network 面板里的网络节流切到 Slow 3G 再刷一次,如果首屏超过 3 秒,优先处理首屏图片的懒加载。静态商城没有后端,首屏速度几乎完全由资源体积决定,把首屏不需要的图片加 loading="lazy" 是性价比最高的优化,一条属性就能显著降低首屏请求阻塞。
最后一步,真机走一遍完整路径:从首页进入列表,点进详情,加购,打开购物车,修改数量,模拟提交。这个过程我不在电脑模拟器上过,因为触摸区域大小、微信返回手势这些只有真机能暴露。把这份 H5商城.zip 下载下来,按第 3 章起服务,再按第 4 章换数据,半小时就能得到你自己的工作版本,改完之后记得把这套检查走一遍,就不用事后找后悔药。
从那以后,我每次交付 H5 商城前都强制自己在手机微信里完整走一遍这条路径,顺手用 Chrome 的 Network 面板导出 HAR 给后端同事看接口耗时,省掉了大量交付后的来回扯皮。希望帮到你。
本文还有配套的精品资源,点击获取