最可靠方式是调用 GitHub/GitLab REST API 获取 JSON 目录结构,需处理认证、分页、Content-Type 分流、路径安全过滤、树形渲染、大文件截断、URL 状态同步及错误边界。

用 fetch 加载 Git 仓库的 raw JSON 目录结构最可靠
GitHub、GitLab 等平台不直接提供 HTML 文件列表接口,但都支持通过 API 获取仓库目录的 JSON 描述(如 GitHub 的 /repos/{owner}/{repo}/contents/)。直接请求 raw HTML 页面会触发重定向或登录跳转,且结构不可靠。必须走 REST API,并处理认证与分页。
常见错误:用 iframe 嵌入 GitHub 页面 —— 会被 X-Frame-Options: deny 拦截;用 XMLHttpRequest 请求 HTML 路径 —— 返回 404 或登录页 HTML,解析失败。
- GitHub 免登录可读公开仓库,但限速(60次/小时),需加
Accept: application/vnd.github.v3+json - 私有仓库必须传
Authorization: Bearer <token>,Token 权限至少含repo(非public_repo) - 目录项中
type === "dir"才能递归请求,type === "file"且size > 0才显示下载/预览链接 - 注意
git_url和download_url区别:前者是 Git 内部引用,后者才是 raw 内容直链
渲染文件树时必须区分 dir 和 file 并处理缩进与图标
纯靠 JSON 数据生成树形结构,不能依赖 CSS margin-left 硬缩进 —— 层级深了会溢出或错位。推荐用嵌套 <ul> + display: none/block 控制展开,但注意:HTML 规范禁止在 <p> 内放 <ul>,所以容器必须用 <div> 或语义化 <section>。
- 每个节点渲染前检查
node.name是否含非法字符(如/、..),防止路径穿越 —— 即使服务端安全,前端也应过滤显示 - 图标用内联 SVG 而非字体图标:避免加载失败导致文字错位,且可直接控制颜色和尺寸
- 文件名过长时用
text-overflow: ellipsis,但必须设white-space: nowrap和固定宽度,否则无效 - 点击目录时,先清空子节点 DOM,再发新请求,避免旧数据残留
预览代码文件要按 MIME 类型做分流,不能全塞进 <pre><code>
GitHub raw 接口返回的不是带 Content-Type: text/plain 的响应,而是根据文件扩展名自动设置(如 .js 是 text/plain,.png 是 image/png)。直接用 fetch().then(r => r.text()) 加载图片会报解析错误。
立即学习“前端免费学习笔记(深入)”;
- 先 HEAD 请求获取
Content-Type,再决定后续逻辑:text/*或application/json→r.text();image/*→r.blob()→URL.createObjectURL();application/pdf→ 单独用<embed> - 代码高亮不要用服务端渲染,前端选轻量库如
highlight.js,只在<pre>内调用hljs.highlightElement(el) - 大文件(>1MB)要限制:显示“文件过大,仅显示前 200 行”,用
ReadableStream流式读取并截断 - 避免把
response.text()结果直接 innerHTML —— 会执行其中的 script 标签,必须用textContent或createTextNode
路由状态必须同步到 URL,否则刷新就丢当前路径
单页浏览仓库时,用户复制链接分享、或刷新页面,应该回到原目录/文件。不能只靠内存变量存 currentPath。
- 用
history.pushState({path}, "", `?path=${encodeURIComponent(path)}`)更新地址栏,不触发刷新 - 监听
popstate事件,在用户点浏览器后退/前进时恢复视图 - 初始加载时从
new URL(window.location).searchParams.get("path")读取,为空则默认""(根目录) - 注意:GitHub 的路径是相对仓库根的,如
src/utils/index.ts,不能带开头斜杠,否则 API 会 404
最易被忽略的是错误边界的处理:API 失败时没 fallback UI,用户看到空白页;文件类型判断漏掉 text/x-shell 这类非标准 type 导致 shell 脚本无法高亮;还有跨域代理配置遗漏,本地开发时直接请求 GitHub API 被 CORS 拦截却没看 console 报错。这些不写进 try/catch 或没显式提示,问题就卡死在用户侧。


















