[{"data":1,"prerenderedAt":3288},["ShallowReactive",2],{"site-search-articles":3,"article-\u002Fblog\u002F40\u002F07-edgeone-ands3-api":403,"article-around-\u002Fblog\u002F40\u002F07-edgeone-ands3-api":3229},[4,17,29,40,51,60,68,76,83,90,98,104,110,116,128,137,145,154,163,170,178,184,190,195,202,210,215,221,226,232,237,245,252,257,264,272,276,282,289,295,299,303,308,313,319,324,328,333,340,346,351,359,365,372,378,385,392,398],{"id":5,"path":6,"title":7,"description":8,"date":9,"tags":10,"category":14,"minutes":15,"pinned":16},"blog\u002Fblog\u002Fnuxt4-vuetify4-blog.md","\u002Fblog\u002Fnuxt4-vuetify4-blog","Nuxt 4 + Vuetify 4 个人博客搭建记录","从内容结构、组件分层到服务端渲染，记录这个博客从零开始的完整实现过程。","2026-08-30",[11,12,13],"Nuxt","Vuetify","博客","开发",12,true,{"id":18,"path":19,"title":20,"description":21,"date":22,"tags":23,"category":26,"minutes":27,"pinned":28},"blog\u002Fblog\u002Fphoto-migration.md","\u002Fblog\u002Fphoto-migration","Google 相册迁移到 iCloud 分享","梳理照片导出、元数据修复与共享图库迁移过程，记录几个容易忽略的细节。","2026-08-26",[24,25],"相册","iCloud","生活",8,false,{"id":30,"path":31,"title":32,"description":33,"date":34,"tags":35,"category":14,"minutes":39,"pinned":28},"blog\u002Fblog\u002Fdocker-proxy.md","\u002Fblog\u002Fdocker-proxy","Docker 部署与反向代理配置","使用多阶段构建、容器重启策略和 Nginx 反向代理完成博客服务的可重复部署。","2026-08-18",[36,37,38],"Docker","Nginx","部署",10,{"id":41,"path":42,"title":43,"description":44,"date":45,"tags":46,"category":49,"minutes":50,"pinned":28},"blog\u002Fblog\u002Fsummer-coast.md","\u002Fblog\u002Fsummer-coast","一组夏日海边照片","把散落在相机和手机里的片段整理成一篇安静的夏日相册。","2026-08-09",[47,48],"摄影","夏日","随记",5,{"id":52,"path":53,"title":54,"description":54,"date":55,"tags":56,"category":59,"minutes":50,"pinned":28},"blog\u002Fblog\u002F40-博客搭建\u002F09-CloudFlare 优选 IP.md","\u002Fblog\u002F40\u002F09-cloudflare-ip","CloudFlare 优选 IP","2026-07-22 03:17:28",[57,58],"Cloudflare","优选域名","Blog",{"id":61,"path":62,"title":63,"description":63,"date":64,"tags":65,"category":59,"minutes":50,"pinned":28},"blog\u002Fblog\u002F40-博客搭建\u002F08-Cloudflare ImgBed 免费私有图床完整部署手册.md","\u002Fblog\u002F40\u002F08-cloudflare-imgbed","Cloudflare ImgBed 免费私有图床完整部署手册","2026-07-19 02:09:08",[57,66,67],"对象存储","图床",{"id":69,"path":70,"title":71,"description":71,"date":72,"tags":73,"category":59,"minutes":50,"pinned":28},"blog\u002Fblog\u002F40-博客搭建\u002F07-腾讯云 EdgeOne 边缘函数实现七牛&S3 随机图床 API.md","\u002Fblog\u002F40\u002F07-edgeone-ands3-api","腾讯云 EdgeOne 边缘函数实现七牛云 & S3 存储随机图床 API","2026-07-13 21:25:48",[74,75,67],"EdgeOne","七牛云",{"id":77,"path":78,"title":79,"description":79,"date":80,"tags":81,"category":59,"minutes":50,"pinned":28},"blog\u002Fblog\u002F40-博客搭建\u002F06-腾讯 EdgeOne 部署 Twikoo 评论系统指南.md","\u002Fblog\u002F40\u002F06-edgeone-twikoo","腾讯EdgeOne部署Twikoo评论系统指南","2026-06-14 17:41:11",[74,82],"Twikoo",{"id":84,"path":85,"title":86,"description":86,"date":87,"tags":88,"category":59,"minutes":50,"pinned":28},"blog\u002Fblog\u002F40-博客搭建\u002F05-OpenList 接入 S3 对象存储完整使用教程.md","\u002Fblog\u002F40\u002F05-openlist-s3","OpenList 接入 S3 对象存储完整使用教程","2026-06-11 13:08:07",[66,89],"OpenList",{"id":91,"path":92,"title":93,"description":94,"date":95,"tags":96,"category":59,"minutes":50,"pinned":28},"blog\u002Fblog\u002F40-博客搭建\u002F04-赛博大善人Cloudflare R2 图床.md","\u002Fblog\u002F40\u002F04-cloudflare-r2","赛博大善人 Cloudflare R2 图床","基于 Cloudflare R2 + 腾讯 Edge One + PicList 搭建免费、全球加速的图床方案","2026-06-09 13:07:35",[59,67,97],"CDN加速",{"id":99,"path":100,"title":101,"description":101,"date":102,"tags":103,"category":59,"minutes":50,"pinned":28},"blog\u002Fblog\u002F40-博客搭建\u002F03-白嫖免费图床，套CDN加速.md","\u002Fblog\u002F40\u002F03-cdn","白嫖免费图床，套 CDN 加速","2026-06-09",[59,67,97],{"id":105,"path":106,"title":107,"description":107,"date":108,"tags":109,"category":59,"minutes":50,"pinned":28},"blog\u002Fblog\u002F40-博客搭建\u002F02-零基础优雅搭建静态博客全教程.md","\u002Fblog\u002F40\u002F02","零基础优雅搭建静态博客全教程","2026-06-04",[59],{"id":111,"path":112,"title":113,"description":113,"date":114,"tags":115,"category":59,"minutes":50,"pinned":28},"blog\u002Fblog\u002F40-博客搭建\u002F01-远古产物—博客.md","\u002Fblog\u002F40\u002F01","赛博空间的私人岛屿：博客架构与风格美学","2026-06-03",[59],{"id":117,"path":118,"title":119,"description":119,"date":120,"tags":121,"category":127,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F20-软路由\u002F15.关于NAT回流与内网域名直连的终极指南.md","\u002Fblog\u002F10\u002F20\u002Fnat","关于 NAT 回流与内网域名直连的终极指南","2026-05-13",[122,123,124,125,126],"docker","DNS","Lucky","NAT 回流","远程访问","软路由",{"id":129,"path":130,"title":131,"description":131,"date":132,"tags":133,"category":134,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F30-NAS\u002F25.基于QMediaSync的飞牛外网strm直连.md","\u002Fblog\u002F10\u002F30-nas\u002Fqmediasyncstrm","基于 Lucky 反代与 QMediaSync 的飞牛外网 STRM 直连","2026-02-08",[134,135,136],"NAS","飞牛 OS","Strm",{"id":138,"path":139,"title":140,"description":140,"date":141,"tags":142,"category":127,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F20-软路由\u002F14.基于飞牛漏洞安全访问lucky反代&雷池防护.md","\u002Fblog\u002F10\u002F20\u002Fluckyand","基于飞牛漏洞安全访问Lucky反代&雷池防护","2026-02-03",[122,143,124,144,126],"WAF","飞牛",{"id":146,"path":147,"title":148,"description":148,"date":149,"tags":150,"category":153,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F60-N1&玩客云&OEC\u002F03.oec-fnOS安装.md","\u002Fblog\u002F10\u002F60-n1andandoec\u002Foec-fnos","OEC-Turbo (RK3566) 安装飞牛 OS","2026-01-24",[151,152,134],"OEC","飞牛OS","N1&玩客云&OEC",{"id":155,"path":156,"title":157,"description":157,"date":158,"tags":159,"category":127,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F20-软路由\u002F13.Lucky反向代理终极指南.md","\u002Fblog\u002F10\u002F20\u002Flucky","Lucky 反向代理终极指南","2026-01-16",[122,160,161,124,162,126],"OpenWRT","IPv4","IPv6",{"id":164,"path":165,"title":166,"description":166,"date":167,"tags":168,"category":122,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F10-docker\u002F11.NAS 导航页的终极形态.md","\u002Fblog\u002F10\u002F10-docker\u002Fnas","告别繁琐配置：NAS 导航页的终极形态 —— 从 Sun-Panel 到 FlatNAS","2026-01-05",[122,134,169],"导航页",{"id":171,"path":172,"title":173,"description":173,"date":174,"tags":175,"category":122,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F10-docker\u002F10.LogVar 弹幕 API 部署指南.md","\u002Fblog\u002F10\u002F10-docker\u002Flogvar-api","LogVar 弹幕 API  (纯本地缓存版) 部署指南","2025-12-30",[122,176,177],"弹幕 API","媒体库",{"id":179,"path":180,"title":181,"description":181,"date":182,"tags":183,"category":134,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F30-NAS\u002F24.飞牛NAS第三方应用商店安装.md","\u002Fblog\u002F10\u002F30-nas\u002Fnas","飞牛 NAS 第三方应用商店 (FnDepot) 安装指南","2025-12-02",[134,135],{"id":185,"path":186,"title":187,"description":187,"date":188,"tags":189,"category":122,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F10-docker\u002F09.兰空图床和高清图标库.md","\u002Fblog\u002F10\u002F10-docker","兰空图床和高清图标库","2025-11-15",[122,67],{"id":191,"path":186,"title":192,"description":192,"date":193,"tags":194,"category":122,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F10-docker\u002F08.你是否需要一个图床？.md","你是否需要一个图床？","2025-11-14",[122,67],{"id":196,"path":197,"title":198,"description":198,"date":199,"tags":200,"category":134,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F30-NAS\u002F23.Hills播放器-Windows-安卓.md","\u002Fblog\u002F10\u002F30-nas\u002Fhills-windows","Hills 播放器（Windows + 安卓）","2025-11-10",[201],"Emby 第三方播放器",{"id":203,"path":204,"title":205,"description":205,"date":206,"tags":207,"category":208,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F50-Linux\u002F02.Debian13换源.md","\u002Fblog\u002F10\u002F50-linux\u002Fdebian13","Debian13 换源","2025-09-10",[208,209],"Linux","debian",{"id":211,"path":212,"title":213,"description":213,"date":206,"tags":214,"category":208,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F50-Linux\u002F04.Linux系统，音响有底噪.md","\u002Fblog\u002F10\u002F50-linux\u002Flinux","Linux 系统，音响有底噪怎么办？",[208],{"id":216,"path":217,"title":218,"description":218,"date":206,"tags":219,"category":208,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F50-Linux\u002F05.一键DD纯净系统脚本.md","\u002Fblog\u002F10\u002F50-linux\u002Fdd","一键 DD 纯净系统脚本",[208,220],"dd 系统",{"id":222,"path":223,"title":224,"description":224,"date":206,"tags":225,"category":208,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F50-Linux\u002F08.一行代码降低服务器功耗.md","\u002Fblog\u002F10\u002F50-linux","一行代码降低服务器功耗",[208,209],{"id":227,"path":228,"title":229,"description":229,"date":206,"tags":230,"category":153,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F60-N1&玩客云&OEC\u002F01.N1盒子永不为奴-Armbian.md","\u002Fblog\u002F10\u002F60-n1andandoec\u002Fn1-armbian","N1 盒子永不为奴 Armbian",[231,208],"N1",{"id":233,"path":234,"title":235,"description":235,"date":206,"tags":236,"category":153,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F60-N1&玩客云&OEC\u002F02.OEC站起来了-Armbian.md","\u002Fblog\u002F10\u002F60-n1andandoec\u002Foec-armbian","OEC 盒子永不为奴 Armbian",[151,208],{"id":238,"path":239,"title":240,"description":241,"date":242,"tags":243,"category":122,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F10-docker\u002F01.容器&docker&docker-compose.md","\u002Fblog\u002F10\u002F10-docker\u002Fanddockeranddocker-compose","容器 & docker & docker-compose","初识 yaml 语法和 docker","2025-08-05",[122,244],"yaml",{"id":246,"path":247,"title":248,"description":249,"date":242,"tags":250,"category":122,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F10-docker\u002F02.容器项目&下载类.md","\u002Fblog\u002F10\u002F10-docker\u002Fand","容器项目&下载类","采用docker搭建下载服务",[122,244,251],"下载",{"id":253,"path":247,"title":254,"description":255,"date":242,"tags":256,"category":122,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F10-docker\u002F03.容器项目&相册类.md","容器项目&相册类","采用 docker 搭建 AI 相册",[122,244,24],{"id":258,"path":247,"title":259,"description":260,"date":242,"tags":261,"category":122,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F10-docker\u002F04.容器项目&影视类.md","容器项目&影视类","采用 docker 影视媒体库",[122,244,262,263],"影视媒体库","Emby",{"id":265,"path":266,"title":267,"description":268,"date":242,"tags":269,"category":122,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F10-docker\u002F05.Emby直连115网盘（一）.md","\u002Fblog\u002F10\u002F10-docker\u002Femby115","Emby直连115网盘（一）","使用 Emby 直连 115 网盘",[122,244,262,263,270,271],"strm","115 网盘",{"id":273,"path":266,"title":274,"description":268,"date":242,"tags":275,"category":122,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F10-docker\u002F06.Emby直连115网盘（二）.md","Emby直连115网盘（二）",[122,244,262,263,270,271],{"id":277,"path":278,"title":279,"description":279,"date":242,"tags":280,"category":122,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F10-docker\u002F07.Adguard Home去广告.md","\u002Fblog\u002F10\u002F10-docker\u002Fadguard-home","Adguard Home 去广告",[122,281],"Adguard Home",{"id":283,"path":284,"title":285,"description":286,"date":242,"tags":287,"category":127,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F20-软路由\u002F01.新的篇章，软路由.md","\u002Fblog\u002F10\u002F20","新的篇章，软路由","初识软路由",[127,288,160],"爱快",{"id":290,"path":284,"title":291,"description":292,"date":242,"tags":293,"category":127,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F20-软路由\u002F02.如何玩公网，怎么远程访问（一）.md","如何玩公网，怎么远程访问（一）","公网远程访问，IPv6也是公网",[127,126,294],"公网 IP",{"id":296,"path":284,"title":297,"description":292,"date":242,"tags":298,"category":127,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F20-软路由\u002F03.如何玩公网，怎么远程访问（二）.md","如何玩公网，怎么远程访问（二）",[127,126,294],{"id":300,"path":284,"title":301,"description":292,"date":242,"tags":302,"category":127,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F20-软路由\u002F04.如何玩公网，怎么远程访问（三）.md","如何玩公网，怎么远程访问（三）",[127,126,294],{"id":304,"path":284,"title":305,"description":305,"date":242,"tags":306,"category":127,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F20-软路由\u002F05.白嫖域名，远程访问.md","白嫖域名，远程访问",[127,126,307],"免费域名",{"id":309,"path":284,"title":310,"description":310,"date":242,"tags":311,"category":127,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F20-软路由\u002F06.没有公网如何远程访问.md","没有公网如何远程访问",[127,126,312],"内网穿透",{"id":314,"path":315,"title":316,"description":316,"date":242,"tags":317,"category":127,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F20-软路由\u002F07.爱快与OpenWRT双软路由MAC地址重复问题修正.md","\u002Fblog\u002F10\u002F20\u002Fopenwrtmac","爱快与 OpenWRT 双软路由MAC地址重复问题修正",[288,160,318],"MAC 地址",{"id":320,"path":321,"title":322,"description":322,"date":242,"tags":323,"category":127,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F20-软路由\u002F08.OpenWRT扩容.md","\u002Fblog\u002F10\u002F20\u002Fopenwrt","OpenWRT 扩容",[160],{"id":325,"path":321,"title":326,"description":326,"date":242,"tags":327,"category":127,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F20-软路由\u002F09.OpenWRT旁路由一条龙教程.md","OpenWRT 旁路由一条龙教程",[160],{"id":329,"path":330,"title":331,"description":331,"date":242,"tags":332,"category":134,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F30-NAS\u002F01.Emby刮削以及尽可能刮削到中文.md","\u002Fblog\u002F10\u002F30-nas\u002Femby","Emby 刮削以及尽可能刮削到中文",[263,177],{"id":334,"path":335,"title":336,"description":336,"date":242,"tags":337,"category":134,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F30-NAS\u002F02.Kodi&CoreELEC安装指南.md","\u002Fblog\u002F10\u002F30-nas\u002Fkodiandcoreelec","Kodi & CoreELEC 安装指南",[338,339,177],"Kodi","CoreELEC",{"id":341,"path":342,"title":343,"description":344,"date":242,"tags":345,"category":134,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F30-NAS\u002F20.飞牛OS的安装.md","\u002Fblog\u002F10\u002F30-nas\u002Fos","飞牛 OS 的安装","初识飞牛 NAS",[134,135],{"id":347,"path":342,"title":348,"description":349,"date":242,"tags":350,"category":134,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F30-NAS\u002F21.飞牛OS安装后必要配置.md","飞牛 OS 安装后必要配置","飞牛 NAS 基础配置",[134,135],{"id":352,"path":353,"title":354,"description":355,"date":242,"tags":356,"category":358,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F40-虚拟机\u002F01.新的篇章，PVE虚拟机.md","\u002Fblog\u002F10\u002F40\u002Fpve","新的篇章，PVE虚拟机","初识 PVE 虚拟机",[208,209,357,358],"PVE","虚拟机",{"id":360,"path":361,"title":362,"description":363,"date":242,"tags":364,"category":358,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F40-虚拟机\u002F03.基于PVE系统安装LXC-debian.md","\u002Fblog\u002F10\u002F40\u002Fpvelxc-debian","基于 PVE 系统安装 LXC-debian","初识 LXC debian",[208,209,357,358],{"id":366,"path":367,"title":368,"description":368,"date":242,"tags":369,"category":358,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F40-虚拟机\u002F07.Ventoy多系统启动盘制作与使用全指南.md","\u002Fblog\u002F10\u002F40\u002Fventoy","Ventoy 多系统启动盘制作与使用全指南",[370,371],"Ventoy","PE 系统",{"id":373,"path":374,"title":375,"description":376,"date":242,"tags":377,"category":358,"minutes":50,"pinned":28},"blog\u002Fblog\u002F10-技术专栏\u002F50-Linux\u002F01.新的篇章，debian12的配置.md","\u002Fblog\u002F10\u002F50-linux\u002Fdebian12","新的篇章，debian12 的配置","初识 debian 12",[208,209],{"id":379,"path":380,"title":381,"description":381,"date":242,"tags":382,"category":383,"minutes":50,"pinned":28},"blog\u002Fblog\u002F20-生活感悟\u002F02.在裂缝中种满阳光.md","\u002Fblog\u002F20","让灵魂带着光行走：在裂缝中种满太阳",[383,384],"生活感悟","随笔记录",{"id":386,"path":387,"title":388,"description":388,"date":242,"tags":389,"category":391,"minutes":50,"pinned":28},"blog\u002Fblog\u002F30-学习笔记\u002F01.Typora学习笔记.md","\u002Fblog\u002F30\u002Ftypora","Typora学习笔记",[390],"Typora","学习笔记",{"id":393,"path":394,"title":395,"description":395,"date":242,"tags":396,"category":391,"minutes":50,"pinned":28},"blog\u002Fblog\u002F30-学习笔记\u002F02.Markdown 拓展.md","\u002Fblog\u002F30\u002Fmarkdown","Markdown 拓展",[397],"Markdown",{"id":399,"path":380,"title":400,"description":400,"date":401,"tags":402,"category":383,"minutes":50,"pinned":28},"blog\u002Fblog\u002F20-生活感悟\u002F01.拥抱生活中的光与热.md","拥抱生活中的光与热","2025-07-05",[383,384],{"id":69,"title":71,"body":404,"category":59,"date":72,"description":71,"draft":28,"extension":3221,"meta":3222,"minutes":50,"navigation":16,"path":70,"pinned":28,"seo":3225,"stem":3226,"tags":3227,"__hash__":3228},{"type":405,"value":406,"toc":3188},"minimark",[407,411,416,425,446,456,459,463,468,496,500,602,606,612,614,618,622,714,742,746,774,776,780,835,848,850,854,858,914,918,942,946,975,2891,2895,2926,2928,2932,2936,2970,2974,2995,2999,3017,3021,3037,3039,3043,3047,3078,3082,3127,3129,3133,3137,3154,3158,3181,3184],[408,409,71],"h1",{"id":410},"腾讯云-edgeone-边缘函数实现七牛云-s3-存储随机图床-api",[412,413,415],"h2",{"id":414},"_1-序言-️","1 序言 🖼️",[417,418,419,420,424],"p",{},"个人静态博客存在壁纸分层展示需求，",[421,422,423],"strong",{},"PC"," 端宽屏壁纸、移动端竖屏壁纸需要两套独立图库，前端直连对象存储存在多重业务痛点：",[426,427,428,432,439],"ul",{},[429,430,431],"li",{},"统一图库混存图片，随机接口返回图片比例与设备不匹配，页面展示效果差；",[429,433,434,435,438],{},"前端直接请求存储域名触发 ",[421,436,437],{},"CORS"," 跨域拦截，同时持续消耗源站下行流量，抬高存储计费；",[429,440,441,442,445],{},"对象存储真实域名、",[421,443,444],{},"AK \u002F SK"," 鉴权密钥暴露客户端，存在文件盗刷、资源泄露风险。",[417,447,448,449,451,452,455],{},"依托腾讯云 ",[421,450,74],{}," 边缘函数搭建代理中间层，边缘节点直出图片二进制流，天然实现 ",[421,453,454],{},"PC \u002F 移动端"," 图库物理隔离、边缘缓存降费、统一跨域处理、全链路异常兜底，无需后端服务即可完成可落地随机图床 API。",[457,458],"hr",{},[412,460,462],{"id":461},"_2-业务需求与方案选型对比","2 业务需求与方案选型对比",[464,465,467],"h3",{"id":466},"_21-项目约束","2.1 项目约束",[426,469,470,476,482,489],{},[429,471,472,473,475],{},"资源分离：",[421,474,423],{},"、移动端图片池使用独立存储目录，通过请求路由自动绑定对应图库，前端无需额外传参区分设备；",[429,477,478,479,481],{},"跨域解决：前端页面直接调用接口，无需在存储侧配置 ",[421,480,437],{},"，兼容 fetch、axios 等主流请求库；",[429,483,484,485,488],{},"缓存降费：边缘节点缓存图片二进制资源，减少七牛云 \u002F ",[421,486,487],{},"S3"," 源站回源请求与下行流量；",[429,490,491,492,495],{},"异常容错：目录无图片、存储鉴权失败、网络超时、资源 ",[421,493,494],{},"404"," 场景自动返回兜底占位图，避免页面空白报错。",[464,497,499],{"id":498},"_22-两种实现方案三线对比","2.2 两种实现方案三线对比",[501,502,503,519],"table",{},[504,505,506],"thead",{},[507,508,509,513,516],"tr",{},[510,511,512],"th",{},"对比维度",[510,514,515],{},"302 重定向方案",[510,517,518],{},"EdgeOne 边缘节点代理直出图片流",[520,521,522,534,545,563,580,591],"tbody",{},[507,523,524,528,531],{},[525,526,527],"td",{},"流量链路",[525,529,530],{},"用户 → 边缘节点 → 302 跳转 → 对象存储源站",[525,532,533],{},"用户 → 就近边缘节点，边缘回源存储拉取图片，二进制流直接返回客户端",[507,535,536,539,542],{},[525,537,538],{},"缓存能力",[525,540,541],{},"仅缓存 302 响应头，图片本体无法缓存",[525,543,544],{},"完整缓存图片二进制数据，同区域重复访问无源站流量",[507,546,547,550,560],{},[525,548,549],{},"密钥安全",[525,551,552,553,556,557,559],{},"前端可捕获存储 ",[421,554,555],{},"CDN"," 域名，",[421,558,444],{}," 存在泄露盗刷风险",[525,561,562],{},"密钥存放边缘环境变量，前端无法感知存储地址与鉴权信息",[507,564,565,568,574],{},[525,566,567],{},"跨域运维",[525,569,570,571,573],{},"每个存储桶单独配置 ",[421,572,437],{},"，多存储场景运维繁琐",[525,575,576,577,579],{},"边缘统一输出跨域响应头，一套规则适配全部 ",[421,578,487],{}," 兼容存储",[507,581,582,585,588],{},[525,583,584],{},"异常降级",[525,586,587],{},"资源失效直接返回 404，无兜底展示逻辑",[525,589,590],{},"边缘捕获全链路异常，自动切换预设兜底图片返回",[507,592,593,596,599],{},[525,594,595],{},"长期成本",[525,597,598],{},"源站下行流量持续消耗，存储计费偏高",[525,600,601],{},"边缘缓存命中占比提升后，源站流量成本大幅下降",[464,603,605],{"id":604},"_23-方案选型结论","2.3 方案选型结论",[417,607,608,609,611],{},"优先选用 ",[421,610,518],{}," 架构。\n该方案在存储安全、流量成本、运维复杂度、异常容错四大维度全面优于 302 重定向，适配静态博客、轻量化站点高频调用随机图床接口的长期运营场景，零后端架构大幅降低服务器运维成本。",[457,613],{},[412,615,617],{"id":616},"_3-整体架构与运行链路","3 整体架构与运行链路",[464,619,621],{"id":620},"_31-完整请求链路流程图文字说明","3.1 完整请求链路流程图文字说明",[623,624,629],"pre",{"className":625,"code":626,"language":627,"meta":628,"style":628},"language-mermaid shiki shiki-themes github-light github-dark","flowchart LR\nA[用户浏览器] --> B[EdgeOne全球边缘节点]\nB --> C{路由匹配判断}\nC -->|\u002Fapi 路由| D[读取PC图库目录 blog\u002Fbg\u002F]\nC -->|\u002Fm-api 路由| E[读取移动端图库目录 blog\u002Fbg-m\u002F]\nD & E --> F[携带鉴权签名请求存储获取图片列表]\nF --> G[随机选取单张图片资源]\nG --> H[边缘回源拉取图片二进制流]\nH --> I[追加跨域、缓存响应头]\nI --> B\nB --> A\nJ[边缘本地缓存图片] --> B\nF -->|请求异常\u002F目录无图| K[加载兜底默认图片]\nK --> I\n","mermaid","",[630,631,632,640,646,652,658,663,669,675,680,686,691,697,702,708],"code",{"__ignoreMap":628},[633,634,637],"span",{"class":635,"line":636},"line",1,[633,638,639],{},"flowchart LR\n",[633,641,643],{"class":635,"line":642},2,[633,644,645],{},"A[用户浏览器] --> B[EdgeOne全球边缘节点]\n",[633,647,649],{"class":635,"line":648},3,[633,650,651],{},"B --> C{路由匹配判断}\n",[633,653,655],{"class":635,"line":654},4,[633,656,657],{},"C -->|\u002Fapi 路由| D[读取PC图库目录 blog\u002Fbg\u002F]\n",[633,659,660],{"class":635,"line":50},[633,661,662],{},"C -->|\u002Fm-api 路由| E[读取移动端图库目录 blog\u002Fbg-m\u002F]\n",[633,664,666],{"class":635,"line":665},6,[633,667,668],{},"D & E --> F[携带鉴权签名请求存储获取图片列表]\n",[633,670,672],{"class":635,"line":671},7,[633,673,674],{},"F --> G[随机选取单张图片资源]\n",[633,676,677],{"class":635,"line":27},[633,678,679],{},"G --> H[边缘回源拉取图片二进制流]\n",[633,681,683],{"class":635,"line":682},9,[633,684,685],{},"H --> I[追加跨域、缓存响应头]\n",[633,687,688],{"class":635,"line":39},[633,689,690],{},"I --> B\n",[633,692,694],{"class":635,"line":693},11,[633,695,696],{},"B --> A\n",[633,698,699],{"class":635,"line":15},[633,700,701],{},"J[边缘本地缓存图片] --> B\n",[633,703,705],{"class":635,"line":704},13,[633,706,707],{},"F -->|请求异常\u002F目录无图| K[加载兜底默认图片]\n",[633,709,711],{"class":635,"line":710},14,[633,712,713],{},"K --> I\n",[426,715,716,730,733,736,739],{},[429,717,718,719,722,723,726,727,729],{},"用户发起 ",[630,720,721],{},"\u002Fapi"," 或 ",[630,724,725],{},"\u002Fm-api"," 接口请求，流量调度至就近 ",[421,728,74],{}," 边缘节点；",[429,731,732],{},"边缘函数匹配请求路由绑定对应资源目录，携带鉴权签名调用存储文件列表接口；",[429,734,735],{},"过滤图片格式后随机选取资源，边缘节点回源拉取图片二进制；",[429,737,738],{},"统一拼接跨域、长缓存响应头，图片流返回客户端并在边缘本地缓存；",[429,740,741],{},"链路任意环节触发异常时，自动加载兜底图片返回，保障页面正常渲染。",[464,743,745],{"id":744},"_32-资源分层规则","3.2 资源分层规则",[426,747,748,761,771],{},[429,749,750,752,753,756,757,760],{},[421,751,423],{}," 端图库目录：",[630,754,755],{},"blog\u002Fbg\u002F","，存放 ",[421,758,759],{},"16:9 \u002F 21:9"," 宽屏高清壁纸，适配桌面端展示；",[429,762,763,764,756,767,770],{},"移动端图库目录：",[630,765,766],{},"blog\u002Fbg-m\u002F",[421,768,769],{},"9:16"," 竖屏壁纸，适配手机、平板竖屏场景；",[429,772,773],{},"两套目录物理隔离，接口路由自动绑定对应目录，前端无需传递设备标识参数。",[457,775],{},[412,777,779],{"id":778},"_4-获取七牛云密钥兼容标准-s3-存储","4 获取七牛云密钥（兼容标准 S3 存储）",[426,781,782,815],{},[429,783,784,785],{},"七牛云密钥获取流程\n",[426,786,787,798,809],{},[429,788,789,790,797],{},"登录",[791,792,796],"a",{"href":793,"rel":794},"https:\u002F\u002Fportal.qiniu.com\u002Fdeveloper\u002Fuser\u002Fkey",[795],"nofollow","七牛云控制台","，进入个人中心 - 密钥管理页面；",[429,799,800,801,804,805,808],{},"复制 ",[421,802,803],{},"AccessKey(AK)","、",[421,806,807],{},"SecretKey(SK)"," 两组鉴权密钥；",[429,810,811,812,814],{},"记录存储空间名称、",[421,813,555],{}," 访问域名、线上兜底图片完整地址。",[429,816,817,819,820,823,824,827,828,830,831],{},[421,818,487],{}," 通用存储适配说明\n阿里云 ",[421,821,822],{},"OSS","、腾讯云 ",[421,825,826],{},"COS","、MinIO 等标准 ",[421,829,487],{}," 对象存储仅需重写签名生成函数、替换存储列表请求域名，边缘代理整体业务逻辑无需改动。\n",[832,833],"img",{"alt":628,"src":834},"https:\u002F\u002Fimg.nw177.cn\u002Fblog\u002F2026\u002F07\u002F13\u002F1783953543543.avif",[836,837,838],"blockquote",{},[417,839,840,841,844,845,847],{},"⚠️ 关键避坑警告：生产环境严禁将 ",[421,842,843],{},"AK、SK"," 密钥硬编码写入边缘函数源码，必须通过 ",[421,846,74],{}," 环境变量配置密钥，防止源码泄露导致存储文件被盗刷、产生高额流量账单。",[457,849],{},[412,851,853],{"id":852},"_5-腾讯-edgeone-边缘函数","5 腾讯 EdgeOne 边缘函数",[464,855,857],{"id":856},"_51-添加触发边缘函数的域名","5.1 添加触发边缘函数的域名",[426,859,860,873,879,885,890,893,908],{},[429,861,862,863,869,870,872],{},"进入 ",[421,864,865],{},[791,866,74],{"href":867,"rel":868},"https:\u002F\u002Fconsole.cloud.tencent.com\u002Fedgeone\u002Fzones",[795]," 控制台站点管理，接入业务域名并完成 ",[421,871,123],{}," 解析生效；",[429,874,875,876],{},"域名配置，加速域名：",[630,877,878],{},"api.img.你的备案域名.com",[429,880,881,882],{},"回源配置，IP 域名：",[421,883,884],{},"119.29.29.29",[429,886,887,888],{},"回源配置，回源 HOST 头：",[630,889,878],{},[429,891,892],{},"不使用模板，下一步解析 DNS 就可以",[429,894,895,896,899,900,903,904,907],{},"配置 ",[421,897,898],{},"SSL"," 证书，开启全站 ",[421,901,902],{},"HTTPS"," 强制跳转，关闭 ",[421,905,906],{},"HTTP"," 明文访问；",[429,909,910,911],{},"开启域名边缘函数执行权限，限制流量直接回源源站。\n",[832,912],{"alt":628,"src":913},"https:\u002F\u002Fimg.nw177.cn\u002Fblog\u002F2026\u002F07\u002F13\u002F1783954579728.avif",[464,915,917],{"id":916},"_52-创建边缘函数","5.2 创建边缘函数",[426,919,920,930,933,936],{},[429,921,922,923,926,927],{},"侧边栏选择边缘函数，新建函数，运行环境选择 ",[421,924,925],{},"创建 Hello World","；\n",[832,928],{"alt":628,"src":929},"https:\u002F\u002Fimg.nw177.cn\u002Fblog\u002F2026\u002F07\u002F13\u002F1783956091651.avif",[429,931,932],{},"函数名称：api-img",[429,934,935],{},"描述：随机图床 API",[429,937,938,939],{},"函数代码：全部删除，填写函数代码，先空着创建部署也可以。\n",[832,940],{"alt":628,"src":941},"https:\u002F\u002Fimg.nw177.cn\u002Fblog\u002F2026\u002F07\u002F13\u002F1783956377110.avif",[464,943,945],{"id":944},"_53-编辑函数代码核心","5.3 编辑函数代码（核心）",[426,947,948,951,954,957,963,966,969],{},[429,949,950],{},"完整边缘函数源码",[429,952,953],{},"AK 密钥、SK 密钥",[429,955,956],{},"BUCKET 存储桶名称，例如 sinc-img",[429,958,959,960],{},"DOMAIN，最好填写套一层 CDN 的，EO的域名",[630,961,962],{},"img.你的备案域名.com",[429,964,965],{},"PC_PREFIX 电脑壁纸存储路径，例如 “blog\u002Fbg\u002F\"",[429,967,968],{},"MOBILE_PREFIX 手机端壁纸存储路径，例如 \"blog\u002Fbg-m\u002F\"",[429,970,971,972],{},"所以，你上传电脑壁纸和手机壁纸，就分别传这俩路径就可以\n",[832,973],{"alt":628,"src":974},"https:\u002F\u002Fimg.nw177.cn\u002Fblog\u002F2026\u002F07\u002F13\u002F1783957368843.avif",[623,976,980],{"className":977,"code":978,"language":979,"meta":628,"style":628},"language-javascript shiki shiki-themes github-light github-dark","\u002F**\n * 随机图 API - 腾讯云 EdgeOne 大满贯版\n * 特性：直连七牛云目录、极速内存缓存、边缘代理(零跨域、非302)\n *\u002F\n\n\u002F\u002F ==========================================\n\u002F\u002F 1. 核心配置区\n\u002F\u002F ==========================================\nconst CONFIG = {\n  AK: \"AK密钥\", \n  SK: \"SK密钥\",\n  BUCKET: \"七牛云存储空间名称\", \n  DOMAIN: \"最好填写套一层CDN的，EO的域名\", \u002F\u002F 你的图床 CDN 域名\n  \n  PC_PREFIX: \"blog\u002Fbg\u002F\",    \n  MOBILE_PREFIX: \"blog\u002Fbg-m\u002F\" \n};\n\n\u002F\u002F ==========================================\n\u002F\u002F 2. 全局内存缓存\n\u002F\u002F ==========================================\nlet pcImages = [];\nlet mobileImages = [];\nlet lastCheckTime = 0;\nconst CACHE_TTL = 3 * 60 * 1000; \u002F\u002F 3 分钟缓存\n\naddEventListener('fetch', event => {\n  event.respondWith(handleRequest(event.request))\n});\n\n\u002F\u002F ==========================================\n\u002F\u002F 3. 密码学：生成七牛云鉴权 Token\n\u002F\u002F ==========================================\nasync function generateQiniuToken(path) {\n  const signingStr = `${path}\\n`;\n  const encoder = new TextEncoder();\n  const key = await crypto.subtle.importKey(\n    'raw', encoder.encode(CONFIG.SK), \n    { name: 'HMAC', hash: 'SHA-1' }, false, ['sign']\n  );\n  const signature = await crypto.subtle.sign('HMAC', key, encoder.encode(signingStr));\n  const base64 = btoa(String.fromCharCode(...new Uint8Array(signature)));\n  const encodedSign = base64.replace(\u002F\\+\u002Fg, '-').replace(\u002F\\\u002F\u002Fg, '_');\n  return `QBox ${CONFIG.AK}:${encodedSign}`;\n}\n\n\u002F\u002F ==========================================\n\u002F\u002F 4. 抓取七牛云真实文件列表\n\u002F\u002F ==========================================\nasync function fetchImagesFromQiniu(prefix) {\n  try {\n    const apiPath = `\u002Flist?bucket=${CONFIG.BUCKET}&prefix=${prefix}&limit=1000`;\n    const apiHost = 'rsf.qiniuapi.com'; \n    const token = await generateQiniuToken(apiPath);\n    \n    const response = await fetch(`https:\u002F\u002F${apiHost}${apiPath}`, {\n      headers: {\n        'Authorization': token,\n        'Content-Type': 'application\u002Fx-www-form-urlencoded'\n      }\n    });\n\n    if (!response.ok) return [];\n\n    const data = await response.json();\n    if (!data.items) return [];\n\n    return data.items\n      .filter(item => item.mimeType && item.mimeType.startsWith('image\u002F'))\n      .map(item => `${CONFIG.DOMAIN}\u002F${item.key}`);\n      \n  } catch (error) {\n    console.error(`拉取目录 ${prefix} 失败:`, error);\n    return [];\n  }\n}\n\n\u002F\u002F ==========================================\n\u002F\u002F 5. 代理获取图片并注入跨域头 (核心新增逻辑)\n\u002F\u002F ==========================================\nasync function proxyImage(imageUrl) {\n  try {\n    \u002F\u002F 边缘节点出面去你的 CDN 拿图\n    const response = await fetch(imageUrl, {\n      headers: {\n        \"User-Agent\": \"Mozilla\u002F5.0 (Windows NT 10.0; Win64; x64) EdgeOne-Proxy\"\n      }\n    });\n\n    if (response.ok) {\n      \u002F\u002F 拿到图片后，重写响应头，强行允许跨域\n      const newHeaders = new Headers(response.headers);\n      newHeaders.set(\"Access-Control-Allow-Origin\", \"*\");\n      newHeaders.set(\"Cache-Control\", \"no-cache\"); \u002F\u002F 告诉浏览器不要缓存当前API链接，以免下次拿不到新图\n\n      \u002F\u002F 返回 200 状态码和真实图片数据流\n      return new Response(response.body, {\n        status: 200,\n        headers: newHeaders\n      });\n    }\n    \n    \u002F\u002F 如果图片代理失败，降级回 302 重定向\n    return Response.redirect(imageUrl, 302);\n  } catch (e) {\n    \u002F\u002F 网络异常，降级回 302 重定向\n    return Response.redirect(imageUrl, 302);\n  }\n}\n\n\u002F\u002F ==========================================\n\u002F\u002F 6. 主路由逻辑\n\u002F\u002F ==========================================\nasync function handleRequest(request) {\n  const url = new URL(request.url);\n  const route = url.pathname;\n\n  \u002F\u002F 初始化或更新缓存\n  if (Date.now() - lastCheckTime > CACHE_TTL || pcImages.length === 0 || mobileImages.length === 0) {\n    try {\n      const [newPc, newMobile] = await Promise.all([\n        fetchImagesFromQiniu(CONFIG.PC_PREFIX),\n        fetchImagesFromQiniu(CONFIG.MOBILE_PREFIX)\n      ]);\n      \n      if (newPc.length > 0) pcImages = newPc;\n      if (newMobile.length > 0) mobileImages = newMobile;\n      lastCheckTime = Date.now();\n    } catch (e) {\n      console.error(\"更新列表失败，暂时使用旧缓存\");\n    }\n  }\n\n  \u002F\u002F --- 处理电脑壁纸 ---\n  if (route === '\u002Fapi') {\n    if (pcImages.length === 0) return new Response(\"初始化中...\", {status: 503});\n    const randomImg = pcImages[Math.floor(Math.random() * pcImages.length)];\n    \u002F\u002F 调用代理函数，直接返回图片流\n    return await proxyImage(randomImg);\n  }\n\n  \u002F\u002F --- 处理手机壁纸 ---\n  if (route === '\u002Fm-api') {\n    if (mobileImages.length === 0) return new Response(\"初始化中...\", {status: 503});\n    const randomImg = mobileImages[Math.floor(Math.random() * mobileImages.length)];\n    \u002F\u002F 调用代理函数，直接返回图片流\n    return await proxyImage(randomImg);\n  }\n\n  return new Response(\"API 正常运行。电脑壁纸请访问 \u002Fapi，手机壁纸请访问 \u002Fm-api\", { \n    status: 200, \n    headers: { \"Content-Type\": \"text\u002Fhtml;charset=UTF-8\" } \n  });\n}\n","javascript",[630,981,982,988,993,998,1003,1008,1013,1018,1022,1039,1051,1062,1072,1086,1091,1103,1115,1121,1126,1131,1137,1142,1157,1169,1185,1215,1220,1244,1261,1267,1272,1277,1283,1288,1308,1335,1354,1376,1402,1432,1438,1467,1497,1556,1583,1589,1594,1599,1605,1610,1627,1635,1666,1682,1699,1705,1739,1745,1754,1766,1772,1778,1783,1803,1808,1828,1844,1849,1858,1894,1931,1937,1949,1971,1978,1984,1989,1994,1999,2005,2010,2027,2034,2040,2056,2061,2072,2077,2082,2087,2095,2101,2120,2141,2164,2169,2175,2189,2200,2206,2212,2218,2223,2229,2248,2258,2264,2279,2284,2289,2294,2299,2305,2310,2327,2345,2358,2363,2369,2421,2429,2463,2481,2498,2504,2509,2533,2555,2570,2580,2595,2600,2605,2610,2616,2632,2668,2702,2708,2720,2725,2730,2736,2750,2782,2810,2815,2826,2831,2836,2853,2863,2880,2886],{"__ignoreMap":628},[633,983,984],{"class":635,"line":636},[633,985,987],{"class":986},"sJ8bj","\u002F**\n",[633,989,990],{"class":635,"line":642},[633,991,992],{"class":986}," * 随机图 API - 腾讯云 EdgeOne 大满贯版\n",[633,994,995],{"class":635,"line":648},[633,996,997],{"class":986}," * 特性：直连七牛云目录、极速内存缓存、边缘代理(零跨域、非302)\n",[633,999,1000],{"class":635,"line":654},[633,1001,1002],{"class":986}," *\u002F\n",[633,1004,1005],{"class":635,"line":50},[633,1006,1007],{"emptyLinePlaceholder":16},"\n",[633,1009,1010],{"class":635,"line":665},[633,1011,1012],{"class":986},"\u002F\u002F ==========================================\n",[633,1014,1015],{"class":635,"line":671},[633,1016,1017],{"class":986},"\u002F\u002F 1. 核心配置区\n",[633,1019,1020],{"class":635,"line":27},[633,1021,1012],{"class":986},[633,1023,1024,1028,1032,1035],{"class":635,"line":682},[633,1025,1027],{"class":1026},"szBVR","const",[633,1029,1031],{"class":1030},"sj4cs"," CONFIG",[633,1033,1034],{"class":1026}," =",[633,1036,1038],{"class":1037},"sVt8B"," {\n",[633,1040,1041,1044,1048],{"class":635,"line":39},[633,1042,1043],{"class":1037},"  AK: ",[633,1045,1047],{"class":1046},"sZZnC","\"AK密钥\"",[633,1049,1050],{"class":1037},", \n",[633,1052,1053,1056,1059],{"class":635,"line":693},[633,1054,1055],{"class":1037},"  SK: ",[633,1057,1058],{"class":1046},"\"SK密钥\"",[633,1060,1061],{"class":1037},",\n",[633,1063,1064,1067,1070],{"class":635,"line":15},[633,1065,1066],{"class":1037},"  BUCKET: ",[633,1068,1069],{"class":1046},"\"七牛云存储空间名称\"",[633,1071,1050],{"class":1037},[633,1073,1074,1077,1080,1083],{"class":635,"line":704},[633,1075,1076],{"class":1037},"  DOMAIN: ",[633,1078,1079],{"class":1046},"\"最好填写套一层CDN的，EO的域名\"",[633,1081,1082],{"class":1037},", ",[633,1084,1085],{"class":986},"\u002F\u002F 你的图床 CDN 域名\n",[633,1087,1088],{"class":635,"line":710},[633,1089,1090],{"class":1037},"  \n",[633,1092,1094,1097,1100],{"class":635,"line":1093},15,[633,1095,1096],{"class":1037},"  PC_PREFIX: ",[633,1098,1099],{"class":1046},"\"blog\u002Fbg\u002F\"",[633,1101,1102],{"class":1037},",    \n",[633,1104,1106,1109,1112],{"class":635,"line":1105},16,[633,1107,1108],{"class":1037},"  MOBILE_PREFIX: ",[633,1110,1111],{"class":1046},"\"blog\u002Fbg-m\u002F\"",[633,1113,1114],{"class":1037}," \n",[633,1116,1118],{"class":635,"line":1117},17,[633,1119,1120],{"class":1037},"};\n",[633,1122,1124],{"class":635,"line":1123},18,[633,1125,1007],{"emptyLinePlaceholder":16},[633,1127,1129],{"class":635,"line":1128},19,[633,1130,1012],{"class":986},[633,1132,1134],{"class":635,"line":1133},20,[633,1135,1136],{"class":986},"\u002F\u002F 2. 全局内存缓存\n",[633,1138,1140],{"class":635,"line":1139},21,[633,1141,1012],{"class":986},[633,1143,1145,1148,1151,1154],{"class":635,"line":1144},22,[633,1146,1147],{"class":1026},"let",[633,1149,1150],{"class":1037}," pcImages ",[633,1152,1153],{"class":1026},"=",[633,1155,1156],{"class":1037}," [];\n",[633,1158,1160,1162,1165,1167],{"class":635,"line":1159},23,[633,1161,1147],{"class":1026},[633,1163,1164],{"class":1037}," mobileImages ",[633,1166,1153],{"class":1026},[633,1168,1156],{"class":1037},[633,1170,1172,1174,1177,1179,1182],{"class":635,"line":1171},24,[633,1173,1147],{"class":1026},[633,1175,1176],{"class":1037}," lastCheckTime ",[633,1178,1153],{"class":1026},[633,1180,1181],{"class":1030}," 0",[633,1183,1184],{"class":1037},";\n",[633,1186,1188,1190,1193,1195,1198,1201,1204,1206,1209,1212],{"class":635,"line":1187},25,[633,1189,1027],{"class":1026},[633,1191,1192],{"class":1030}," CACHE_TTL",[633,1194,1034],{"class":1026},[633,1196,1197],{"class":1030}," 3",[633,1199,1200],{"class":1026}," *",[633,1202,1203],{"class":1030}," 60",[633,1205,1200],{"class":1026},[633,1207,1208],{"class":1030}," 1000",[633,1210,1211],{"class":1037},"; ",[633,1213,1214],{"class":986},"\u002F\u002F 3 分钟缓存\n",[633,1216,1218],{"class":635,"line":1217},26,[633,1219,1007],{"emptyLinePlaceholder":16},[633,1221,1223,1227,1230,1233,1235,1239,1242],{"class":635,"line":1222},27,[633,1224,1226],{"class":1225},"sScJk","addEventListener",[633,1228,1229],{"class":1037},"(",[633,1231,1232],{"class":1046},"'fetch'",[633,1234,1082],{"class":1037},[633,1236,1238],{"class":1237},"s4XuR","event",[633,1240,1241],{"class":1026}," =>",[633,1243,1038],{"class":1037},[633,1245,1247,1250,1253,1255,1258],{"class":635,"line":1246},28,[633,1248,1249],{"class":1037},"  event.",[633,1251,1252],{"class":1225},"respondWith",[633,1254,1229],{"class":1037},[633,1256,1257],{"class":1225},"handleRequest",[633,1259,1260],{"class":1037},"(event.request))\n",[633,1262,1264],{"class":635,"line":1263},29,[633,1265,1266],{"class":1037},"});\n",[633,1268,1270],{"class":635,"line":1269},30,[633,1271,1007],{"emptyLinePlaceholder":16},[633,1273,1275],{"class":635,"line":1274},31,[633,1276,1012],{"class":986},[633,1278,1280],{"class":635,"line":1279},32,[633,1281,1282],{"class":986},"\u002F\u002F 3. 密码学：生成七牛云鉴权 Token\n",[633,1284,1286],{"class":635,"line":1285},33,[633,1287,1012],{"class":986},[633,1289,1291,1294,1297,1300,1302,1305],{"class":635,"line":1290},34,[633,1292,1293],{"class":1026},"async",[633,1295,1296],{"class":1026}," function",[633,1298,1299],{"class":1225}," generateQiniuToken",[633,1301,1229],{"class":1037},[633,1303,1304],{"class":1237},"path",[633,1306,1307],{"class":1037},") {\n",[633,1309,1311,1314,1317,1319,1322,1324,1327,1330,1333],{"class":635,"line":1310},35,[633,1312,1313],{"class":1026},"  const",[633,1315,1316],{"class":1030}," signingStr",[633,1318,1034],{"class":1026},[633,1320,1321],{"class":1046}," `${",[633,1323,1304],{"class":1037},[633,1325,1326],{"class":1046},"}",[633,1328,1329],{"class":1030},"\\n",[633,1331,1332],{"class":1046},"`",[633,1334,1184],{"class":1037},[633,1336,1338,1340,1343,1345,1348,1351],{"class":635,"line":1337},36,[633,1339,1313],{"class":1026},[633,1341,1342],{"class":1030}," encoder",[633,1344,1034],{"class":1026},[633,1346,1347],{"class":1026}," new",[633,1349,1350],{"class":1225}," TextEncoder",[633,1352,1353],{"class":1037},"();\n",[633,1355,1357,1359,1362,1364,1367,1370,1373],{"class":635,"line":1356},37,[633,1358,1313],{"class":1026},[633,1360,1361],{"class":1030}," key",[633,1363,1034],{"class":1026},[633,1365,1366],{"class":1026}," await",[633,1368,1369],{"class":1037}," crypto.subtle.",[633,1371,1372],{"class":1225},"importKey",[633,1374,1375],{"class":1037},"(\n",[633,1377,1379,1382,1385,1388,1390,1393,1396,1399],{"class":635,"line":1378},38,[633,1380,1381],{"class":1046},"    'raw'",[633,1383,1384],{"class":1037},", encoder.",[633,1386,1387],{"class":1225},"encode",[633,1389,1229],{"class":1037},[633,1391,1392],{"class":1030},"CONFIG",[633,1394,1395],{"class":1037},".",[633,1397,1398],{"class":1030},"SK",[633,1400,1401],{"class":1037},"), \n",[633,1403,1405,1408,1411,1414,1417,1420,1423,1426,1429],{"class":635,"line":1404},39,[633,1406,1407],{"class":1037},"    { name: ",[633,1409,1410],{"class":1046},"'HMAC'",[633,1412,1413],{"class":1037},", hash: ",[633,1415,1416],{"class":1046},"'SHA-1'",[633,1418,1419],{"class":1037}," }, ",[633,1421,1422],{"class":1030},"false",[633,1424,1425],{"class":1037},", [",[633,1427,1428],{"class":1046},"'sign'",[633,1430,1431],{"class":1037},"]\n",[633,1433,1435],{"class":635,"line":1434},40,[633,1436,1437],{"class":1037},"  );\n",[633,1439,1441,1443,1446,1448,1450,1452,1455,1457,1459,1462,1464],{"class":635,"line":1440},41,[633,1442,1313],{"class":1026},[633,1444,1445],{"class":1030}," signature",[633,1447,1034],{"class":1026},[633,1449,1366],{"class":1026},[633,1451,1369],{"class":1037},[633,1453,1454],{"class":1225},"sign",[633,1456,1229],{"class":1037},[633,1458,1410],{"class":1046},[633,1460,1461],{"class":1037},", key, encoder.",[633,1463,1387],{"class":1225},[633,1465,1466],{"class":1037},"(signingStr));\n",[633,1468,1470,1472,1475,1477,1480,1483,1486,1488,1491,1494],{"class":635,"line":1469},42,[633,1471,1313],{"class":1026},[633,1473,1474],{"class":1030}," base64",[633,1476,1034],{"class":1026},[633,1478,1479],{"class":1225}," btoa",[633,1481,1482],{"class":1037},"(String.",[633,1484,1485],{"class":1225},"fromCharCode",[633,1487,1229],{"class":1037},[633,1489,1490],{"class":1026},"...new",[633,1492,1493],{"class":1225}," Uint8Array",[633,1495,1496],{"class":1037},"(signature)));\n",[633,1498,1500,1502,1505,1507,1510,1513,1515,1518,1522,1524,1527,1529,1532,1535,1537,1539,1541,1544,1546,1548,1550,1553],{"class":635,"line":1499},43,[633,1501,1313],{"class":1026},[633,1503,1504],{"class":1030}," encodedSign",[633,1506,1034],{"class":1026},[633,1508,1509],{"class":1037}," base64.",[633,1511,1512],{"class":1225},"replace",[633,1514,1229],{"class":1037},[633,1516,1517],{"class":1046},"\u002F",[633,1519,1521],{"class":1520},"snhLl","\\+",[633,1523,1517],{"class":1046},[633,1525,1526],{"class":1026},"g",[633,1528,1082],{"class":1037},[633,1530,1531],{"class":1046},"'-'",[633,1533,1534],{"class":1037},").",[633,1536,1512],{"class":1225},[633,1538,1229],{"class":1037},[633,1540,1517],{"class":1046},[633,1542,1543],{"class":1520},"\\\u002F",[633,1545,1517],{"class":1046},[633,1547,1526],{"class":1026},[633,1549,1082],{"class":1037},[633,1551,1552],{"class":1046},"'_'",[633,1554,1555],{"class":1037},");\n",[633,1557,1559,1562,1565,1567,1569,1572,1575,1578,1581],{"class":635,"line":1558},44,[633,1560,1561],{"class":1026},"  return",[633,1563,1564],{"class":1046}," `QBox ${",[633,1566,1392],{"class":1030},[633,1568,1395],{"class":1046},[633,1570,1571],{"class":1030},"AK",[633,1573,1574],{"class":1046},"}:${",[633,1576,1577],{"class":1037},"encodedSign",[633,1579,1580],{"class":1046},"}`",[633,1582,1184],{"class":1037},[633,1584,1586],{"class":635,"line":1585},45,[633,1587,1588],{"class":1037},"}\n",[633,1590,1592],{"class":635,"line":1591},46,[633,1593,1007],{"emptyLinePlaceholder":16},[633,1595,1597],{"class":635,"line":1596},47,[633,1598,1012],{"class":986},[633,1600,1602],{"class":635,"line":1601},48,[633,1603,1604],{"class":986},"\u002F\u002F 4. 抓取七牛云真实文件列表\n",[633,1606,1608],{"class":635,"line":1607},49,[633,1609,1012],{"class":986},[633,1611,1613,1615,1617,1620,1622,1625],{"class":635,"line":1612},50,[633,1614,1293],{"class":1026},[633,1616,1296],{"class":1026},[633,1618,1619],{"class":1225}," fetchImagesFromQiniu",[633,1621,1229],{"class":1037},[633,1623,1624],{"class":1237},"prefix",[633,1626,1307],{"class":1037},[633,1628,1630,1633],{"class":635,"line":1629},51,[633,1631,1632],{"class":1026},"  try",[633,1634,1038],{"class":1037},[633,1636,1638,1641,1644,1646,1649,1651,1653,1656,1659,1661,1664],{"class":635,"line":1637},52,[633,1639,1640],{"class":1026},"    const",[633,1642,1643],{"class":1030}," apiPath",[633,1645,1034],{"class":1026},[633,1647,1648],{"class":1046}," `\u002Flist?bucket=${",[633,1650,1392],{"class":1030},[633,1652,1395],{"class":1046},[633,1654,1655],{"class":1030},"BUCKET",[633,1657,1658],{"class":1046},"}&prefix=${",[633,1660,1624],{"class":1037},[633,1662,1663],{"class":1046},"}&limit=1000`",[633,1665,1184],{"class":1037},[633,1667,1669,1671,1674,1676,1679],{"class":635,"line":1668},53,[633,1670,1640],{"class":1026},[633,1672,1673],{"class":1030}," apiHost",[633,1675,1034],{"class":1026},[633,1677,1678],{"class":1046}," 'rsf.qiniuapi.com'",[633,1680,1681],{"class":1037},"; \n",[633,1683,1685,1687,1690,1692,1694,1696],{"class":635,"line":1684},54,[633,1686,1640],{"class":1026},[633,1688,1689],{"class":1030}," token",[633,1691,1034],{"class":1026},[633,1693,1366],{"class":1026},[633,1695,1299],{"class":1225},[633,1697,1698],{"class":1037},"(apiPath);\n",[633,1700,1702],{"class":635,"line":1701},55,[633,1703,1704],{"class":1037},"    \n",[633,1706,1708,1710,1713,1715,1717,1720,1722,1725,1728,1731,1734,1736],{"class":635,"line":1707},56,[633,1709,1640],{"class":1026},[633,1711,1712],{"class":1030}," response",[633,1714,1034],{"class":1026},[633,1716,1366],{"class":1026},[633,1718,1719],{"class":1225}," fetch",[633,1721,1229],{"class":1037},[633,1723,1724],{"class":1046},"`https:\u002F\u002F${",[633,1726,1727],{"class":1037},"apiHost",[633,1729,1730],{"class":1046},"}${",[633,1732,1733],{"class":1037},"apiPath",[633,1735,1580],{"class":1046},[633,1737,1738],{"class":1037},", {\n",[633,1740,1742],{"class":635,"line":1741},57,[633,1743,1744],{"class":1037},"      headers: {\n",[633,1746,1748,1751],{"class":635,"line":1747},58,[633,1749,1750],{"class":1046},"        'Authorization'",[633,1752,1753],{"class":1037},": token,\n",[633,1755,1757,1760,1763],{"class":635,"line":1756},59,[633,1758,1759],{"class":1046},"        'Content-Type'",[633,1761,1762],{"class":1037},": ",[633,1764,1765],{"class":1046},"'application\u002Fx-www-form-urlencoded'\n",[633,1767,1769],{"class":635,"line":1768},60,[633,1770,1771],{"class":1037},"      }\n",[633,1773,1775],{"class":635,"line":1774},61,[633,1776,1777],{"class":1037},"    });\n",[633,1779,1781],{"class":635,"line":1780},62,[633,1782,1007],{"emptyLinePlaceholder":16},[633,1784,1786,1789,1792,1795,1798,1801],{"class":635,"line":1785},63,[633,1787,1788],{"class":1026},"    if",[633,1790,1791],{"class":1037}," (",[633,1793,1794],{"class":1026},"!",[633,1796,1797],{"class":1037},"response.ok) ",[633,1799,1800],{"class":1026},"return",[633,1802,1156],{"class":1037},[633,1804,1806],{"class":635,"line":1805},64,[633,1807,1007],{"emptyLinePlaceholder":16},[633,1809,1811,1813,1816,1818,1820,1823,1826],{"class":635,"line":1810},65,[633,1812,1640],{"class":1026},[633,1814,1815],{"class":1030}," data",[633,1817,1034],{"class":1026},[633,1819,1366],{"class":1026},[633,1821,1822],{"class":1037}," response.",[633,1824,1825],{"class":1225},"json",[633,1827,1353],{"class":1037},[633,1829,1831,1833,1835,1837,1840,1842],{"class":635,"line":1830},66,[633,1832,1788],{"class":1026},[633,1834,1791],{"class":1037},[633,1836,1794],{"class":1026},[633,1838,1839],{"class":1037},"data.items) ",[633,1841,1800],{"class":1026},[633,1843,1156],{"class":1037},[633,1845,1847],{"class":635,"line":1846},67,[633,1848,1007],{"emptyLinePlaceholder":16},[633,1850,1852,1855],{"class":635,"line":1851},68,[633,1853,1854],{"class":1026},"    return",[633,1856,1857],{"class":1037}," data.items\n",[633,1859,1861,1864,1867,1869,1872,1874,1877,1880,1883,1886,1888,1891],{"class":635,"line":1860},69,[633,1862,1863],{"class":1037},"      .",[633,1865,1866],{"class":1225},"filter",[633,1868,1229],{"class":1037},[633,1870,1871],{"class":1237},"item",[633,1873,1241],{"class":1026},[633,1875,1876],{"class":1037}," item.mimeType ",[633,1878,1879],{"class":1026},"&&",[633,1881,1882],{"class":1037}," item.mimeType.",[633,1884,1885],{"class":1225},"startsWith",[633,1887,1229],{"class":1037},[633,1889,1890],{"class":1046},"'image\u002F'",[633,1892,1893],{"class":1037},"))\n",[633,1895,1897,1899,1902,1904,1906,1908,1910,1912,1914,1917,1920,1922,1924,1927,1929],{"class":635,"line":1896},70,[633,1898,1863],{"class":1037},[633,1900,1901],{"class":1225},"map",[633,1903,1229],{"class":1037},[633,1905,1871],{"class":1237},[633,1907,1241],{"class":1026},[633,1909,1321],{"class":1046},[633,1911,1392],{"class":1030},[633,1913,1395],{"class":1046},[633,1915,1916],{"class":1030},"DOMAIN",[633,1918,1919],{"class":1046},"}\u002F${",[633,1921,1871],{"class":1037},[633,1923,1395],{"class":1046},[633,1925,1926],{"class":1037},"key",[633,1928,1580],{"class":1046},[633,1930,1555],{"class":1037},[633,1932,1934],{"class":635,"line":1933},71,[633,1935,1936],{"class":1037},"      \n",[633,1938,1940,1943,1946],{"class":635,"line":1939},72,[633,1941,1942],{"class":1037},"  } ",[633,1944,1945],{"class":1026},"catch",[633,1947,1948],{"class":1037}," (error) {\n",[633,1950,1952,1955,1958,1960,1963,1965,1968],{"class":635,"line":1951},73,[633,1953,1954],{"class":1037},"    console.",[633,1956,1957],{"class":1225},"error",[633,1959,1229],{"class":1037},[633,1961,1962],{"class":1046},"`拉取目录 ${",[633,1964,1624],{"class":1037},[633,1966,1967],{"class":1046},"} 失败:`",[633,1969,1970],{"class":1037},", error);\n",[633,1972,1974,1976],{"class":635,"line":1973},74,[633,1975,1854],{"class":1026},[633,1977,1156],{"class":1037},[633,1979,1981],{"class":635,"line":1980},75,[633,1982,1983],{"class":1037},"  }\n",[633,1985,1987],{"class":635,"line":1986},76,[633,1988,1588],{"class":1037},[633,1990,1992],{"class":635,"line":1991},77,[633,1993,1007],{"emptyLinePlaceholder":16},[633,1995,1997],{"class":635,"line":1996},78,[633,1998,1012],{"class":986},[633,2000,2002],{"class":635,"line":2001},79,[633,2003,2004],{"class":986},"\u002F\u002F 5. 代理获取图片并注入跨域头 (核心新增逻辑)\n",[633,2006,2008],{"class":635,"line":2007},80,[633,2009,1012],{"class":986},[633,2011,2013,2015,2017,2020,2022,2025],{"class":635,"line":2012},81,[633,2014,1293],{"class":1026},[633,2016,1296],{"class":1026},[633,2018,2019],{"class":1225}," proxyImage",[633,2021,1229],{"class":1037},[633,2023,2024],{"class":1237},"imageUrl",[633,2026,1307],{"class":1037},[633,2028,2030,2032],{"class":635,"line":2029},82,[633,2031,1632],{"class":1026},[633,2033,1038],{"class":1037},[633,2035,2037],{"class":635,"line":2036},83,[633,2038,2039],{"class":986},"    \u002F\u002F 边缘节点出面去你的 CDN 拿图\n",[633,2041,2043,2045,2047,2049,2051,2053],{"class":635,"line":2042},84,[633,2044,1640],{"class":1026},[633,2046,1712],{"class":1030},[633,2048,1034],{"class":1026},[633,2050,1366],{"class":1026},[633,2052,1719],{"class":1225},[633,2054,2055],{"class":1037},"(imageUrl, {\n",[633,2057,2059],{"class":635,"line":2058},85,[633,2060,1744],{"class":1037},[633,2062,2064,2067,2069],{"class":635,"line":2063},86,[633,2065,2066],{"class":1046},"        \"User-Agent\"",[633,2068,1762],{"class":1037},[633,2070,2071],{"class":1046},"\"Mozilla\u002F5.0 (Windows NT 10.0; Win64; x64) EdgeOne-Proxy\"\n",[633,2073,2075],{"class":635,"line":2074},87,[633,2076,1771],{"class":1037},[633,2078,2080],{"class":635,"line":2079},88,[633,2081,1777],{"class":1037},[633,2083,2085],{"class":635,"line":2084},89,[633,2086,1007],{"emptyLinePlaceholder":16},[633,2088,2090,2092],{"class":635,"line":2089},90,[633,2091,1788],{"class":1026},[633,2093,2094],{"class":1037}," (response.ok) {\n",[633,2096,2098],{"class":635,"line":2097},91,[633,2099,2100],{"class":986},"      \u002F\u002F 拿到图片后，重写响应头，强行允许跨域\n",[633,2102,2104,2107,2110,2112,2114,2117],{"class":635,"line":2103},92,[633,2105,2106],{"class":1026},"      const",[633,2108,2109],{"class":1030}," newHeaders",[633,2111,1034],{"class":1026},[633,2113,1347],{"class":1026},[633,2115,2116],{"class":1225}," Headers",[633,2118,2119],{"class":1037},"(response.headers);\n",[633,2121,2123,2126,2129,2131,2134,2136,2139],{"class":635,"line":2122},93,[633,2124,2125],{"class":1037},"      newHeaders.",[633,2127,2128],{"class":1225},"set",[633,2130,1229],{"class":1037},[633,2132,2133],{"class":1046},"\"Access-Control-Allow-Origin\"",[633,2135,1082],{"class":1037},[633,2137,2138],{"class":1046},"\"*\"",[633,2140,1555],{"class":1037},[633,2142,2144,2146,2148,2150,2153,2155,2158,2161],{"class":635,"line":2143},94,[633,2145,2125],{"class":1037},[633,2147,2128],{"class":1225},[633,2149,1229],{"class":1037},[633,2151,2152],{"class":1046},"\"Cache-Control\"",[633,2154,1082],{"class":1037},[633,2156,2157],{"class":1046},"\"no-cache\"",[633,2159,2160],{"class":1037},"); ",[633,2162,2163],{"class":986},"\u002F\u002F 告诉浏览器不要缓存当前API链接，以免下次拿不到新图\n",[633,2165,2167],{"class":635,"line":2166},95,[633,2168,1007],{"emptyLinePlaceholder":16},[633,2170,2172],{"class":635,"line":2171},96,[633,2173,2174],{"class":986},"      \u002F\u002F 返回 200 状态码和真实图片数据流\n",[633,2176,2178,2181,2183,2186],{"class":635,"line":2177},97,[633,2179,2180],{"class":1026},"      return",[633,2182,1347],{"class":1026},[633,2184,2185],{"class":1225}," Response",[633,2187,2188],{"class":1037},"(response.body, {\n",[633,2190,2192,2195,2198],{"class":635,"line":2191},98,[633,2193,2194],{"class":1037},"        status: ",[633,2196,2197],{"class":1030},"200",[633,2199,1061],{"class":1037},[633,2201,2203],{"class":635,"line":2202},99,[633,2204,2205],{"class":1037},"        headers: newHeaders\n",[633,2207,2209],{"class":635,"line":2208},100,[633,2210,2211],{"class":1037},"      });\n",[633,2213,2215],{"class":635,"line":2214},101,[633,2216,2217],{"class":1037},"    }\n",[633,2219,2221],{"class":635,"line":2220},102,[633,2222,1704],{"class":1037},[633,2224,2226],{"class":635,"line":2225},103,[633,2227,2228],{"class":986},"    \u002F\u002F 如果图片代理失败，降级回 302 重定向\n",[633,2230,2232,2234,2237,2240,2243,2246],{"class":635,"line":2231},104,[633,2233,1854],{"class":1026},[633,2235,2236],{"class":1037}," Response.",[633,2238,2239],{"class":1225},"redirect",[633,2241,2242],{"class":1037},"(imageUrl, ",[633,2244,2245],{"class":1030},"302",[633,2247,1555],{"class":1037},[633,2249,2251,2253,2255],{"class":635,"line":2250},105,[633,2252,1942],{"class":1037},[633,2254,1945],{"class":1026},[633,2256,2257],{"class":1037}," (e) {\n",[633,2259,2261],{"class":635,"line":2260},106,[633,2262,2263],{"class":986},"    \u002F\u002F 网络异常，降级回 302 重定向\n",[633,2265,2267,2269,2271,2273,2275,2277],{"class":635,"line":2266},107,[633,2268,1854],{"class":1026},[633,2270,2236],{"class":1037},[633,2272,2239],{"class":1225},[633,2274,2242],{"class":1037},[633,2276,2245],{"class":1030},[633,2278,1555],{"class":1037},[633,2280,2282],{"class":635,"line":2281},108,[633,2283,1983],{"class":1037},[633,2285,2287],{"class":635,"line":2286},109,[633,2288,1588],{"class":1037},[633,2290,2292],{"class":635,"line":2291},110,[633,2293,1007],{"emptyLinePlaceholder":16},[633,2295,2297],{"class":635,"line":2296},111,[633,2298,1012],{"class":986},[633,2300,2302],{"class":635,"line":2301},112,[633,2303,2304],{"class":986},"\u002F\u002F 6. 主路由逻辑\n",[633,2306,2308],{"class":635,"line":2307},113,[633,2309,1012],{"class":986},[633,2311,2313,2315,2317,2320,2322,2325],{"class":635,"line":2312},114,[633,2314,1293],{"class":1026},[633,2316,1296],{"class":1026},[633,2318,2319],{"class":1225}," handleRequest",[633,2321,1229],{"class":1037},[633,2323,2324],{"class":1237},"request",[633,2326,1307],{"class":1037},[633,2328,2330,2332,2335,2337,2339,2342],{"class":635,"line":2329},115,[633,2331,1313],{"class":1026},[633,2333,2334],{"class":1030}," url",[633,2336,1034],{"class":1026},[633,2338,1347],{"class":1026},[633,2340,2341],{"class":1225}," URL",[633,2343,2344],{"class":1037},"(request.url);\n",[633,2346,2348,2350,2353,2355],{"class":635,"line":2347},116,[633,2349,1313],{"class":1026},[633,2351,2352],{"class":1030}," route",[633,2354,1034],{"class":1026},[633,2356,2357],{"class":1037}," url.pathname;\n",[633,2359,2361],{"class":635,"line":2360},117,[633,2362,1007],{"emptyLinePlaceholder":16},[633,2364,2366],{"class":635,"line":2365},118,[633,2367,2368],{"class":986},"  \u002F\u002F 初始化或更新缓存\n",[633,2370,2372,2375,2378,2381,2384,2387,2389,2392,2394,2397,2400,2403,2406,2408,2410,2413,2415,2417,2419],{"class":635,"line":2371},119,[633,2373,2374],{"class":1026},"  if",[633,2376,2377],{"class":1037}," (Date.",[633,2379,2380],{"class":1225},"now",[633,2382,2383],{"class":1037},"() ",[633,2385,2386],{"class":1026},"-",[633,2388,1176],{"class":1037},[633,2390,2391],{"class":1026},">",[633,2393,1192],{"class":1030},[633,2395,2396],{"class":1026}," ||",[633,2398,2399],{"class":1037}," pcImages.",[633,2401,2402],{"class":1030},"length",[633,2404,2405],{"class":1026}," ===",[633,2407,1181],{"class":1030},[633,2409,2396],{"class":1026},[633,2411,2412],{"class":1037}," mobileImages.",[633,2414,2402],{"class":1030},[633,2416,2405],{"class":1026},[633,2418,1181],{"class":1030},[633,2420,1307],{"class":1037},[633,2422,2424,2427],{"class":635,"line":2423},120,[633,2425,2426],{"class":1026},"    try",[633,2428,1038],{"class":1037},[633,2430,2432,2434,2437,2440,2442,2445,2448,2450,2452,2455,2457,2460],{"class":635,"line":2431},121,[633,2433,2106],{"class":1026},[633,2435,2436],{"class":1037}," [",[633,2438,2439],{"class":1030},"newPc",[633,2441,1082],{"class":1037},[633,2443,2444],{"class":1030},"newMobile",[633,2446,2447],{"class":1037},"] ",[633,2449,1153],{"class":1026},[633,2451,1366],{"class":1026},[633,2453,2454],{"class":1030}," Promise",[633,2456,1395],{"class":1037},[633,2458,2459],{"class":1225},"all",[633,2461,2462],{"class":1037},"([\n",[633,2464,2466,2469,2471,2473,2475,2478],{"class":635,"line":2465},122,[633,2467,2468],{"class":1225},"        fetchImagesFromQiniu",[633,2470,1229],{"class":1037},[633,2472,1392],{"class":1030},[633,2474,1395],{"class":1037},[633,2476,2477],{"class":1030},"PC_PREFIX",[633,2479,2480],{"class":1037},"),\n",[633,2482,2484,2486,2488,2490,2492,2495],{"class":635,"line":2483},123,[633,2485,2468],{"class":1225},[633,2487,1229],{"class":1037},[633,2489,1392],{"class":1030},[633,2491,1395],{"class":1037},[633,2493,2494],{"class":1030},"MOBILE_PREFIX",[633,2496,2497],{"class":1037},")\n",[633,2499,2501],{"class":635,"line":2500},124,[633,2502,2503],{"class":1037},"      ]);\n",[633,2505,2507],{"class":635,"line":2506},125,[633,2508,1936],{"class":1037},[633,2510,2512,2515,2518,2520,2523,2525,2528,2530],{"class":635,"line":2511},126,[633,2513,2514],{"class":1026},"      if",[633,2516,2517],{"class":1037}," (newPc.",[633,2519,2402],{"class":1030},[633,2521,2522],{"class":1026}," >",[633,2524,1181],{"class":1030},[633,2526,2527],{"class":1037},") pcImages ",[633,2529,1153],{"class":1026},[633,2531,2532],{"class":1037}," newPc;\n",[633,2534,2536,2538,2541,2543,2545,2547,2550,2552],{"class":635,"line":2535},127,[633,2537,2514],{"class":1026},[633,2539,2540],{"class":1037}," (newMobile.",[633,2542,2402],{"class":1030},[633,2544,2522],{"class":1026},[633,2546,1181],{"class":1030},[633,2548,2549],{"class":1037},") mobileImages ",[633,2551,1153],{"class":1026},[633,2553,2554],{"class":1037}," newMobile;\n",[633,2556,2558,2561,2563,2566,2568],{"class":635,"line":2557},128,[633,2559,2560],{"class":1037},"      lastCheckTime ",[633,2562,1153],{"class":1026},[633,2564,2565],{"class":1037}," Date.",[633,2567,2380],{"class":1225},[633,2569,1353],{"class":1037},[633,2571,2573,2576,2578],{"class":635,"line":2572},129,[633,2574,2575],{"class":1037},"    } ",[633,2577,1945],{"class":1026},[633,2579,2257],{"class":1037},[633,2581,2583,2586,2588,2590,2593],{"class":635,"line":2582},130,[633,2584,2585],{"class":1037},"      console.",[633,2587,1957],{"class":1225},[633,2589,1229],{"class":1037},[633,2591,2592],{"class":1046},"\"更新列表失败，暂时使用旧缓存\"",[633,2594,1555],{"class":1037},[633,2596,2598],{"class":635,"line":2597},131,[633,2599,2217],{"class":1037},[633,2601,2603],{"class":635,"line":2602},132,[633,2604,1983],{"class":1037},[633,2606,2608],{"class":635,"line":2607},133,[633,2609,1007],{"emptyLinePlaceholder":16},[633,2611,2613],{"class":635,"line":2612},134,[633,2614,2615],{"class":986},"  \u002F\u002F --- 处理电脑壁纸 ---\n",[633,2617,2619,2621,2624,2627,2630],{"class":635,"line":2618},135,[633,2620,2374],{"class":1026},[633,2622,2623],{"class":1037}," (route ",[633,2625,2626],{"class":1026},"===",[633,2628,2629],{"class":1046}," '\u002Fapi'",[633,2631,1307],{"class":1037},[633,2633,2635,2637,2640,2642,2644,2646,2649,2651,2653,2655,2657,2660,2663,2666],{"class":635,"line":2634},136,[633,2636,1788],{"class":1026},[633,2638,2639],{"class":1037}," (pcImages.",[633,2641,2402],{"class":1030},[633,2643,2405],{"class":1026},[633,2645,1181],{"class":1030},[633,2647,2648],{"class":1037},") ",[633,2650,1800],{"class":1026},[633,2652,1347],{"class":1026},[633,2654,2185],{"class":1225},[633,2656,1229],{"class":1037},[633,2658,2659],{"class":1046},"\"初始化中...\"",[633,2661,2662],{"class":1037},", {status: ",[633,2664,2665],{"class":1030},"503",[633,2667,1266],{"class":1037},[633,2669,2671,2673,2676,2678,2681,2684,2687,2690,2692,2695,2697,2699],{"class":635,"line":2670},137,[633,2672,1640],{"class":1026},[633,2674,2675],{"class":1030}," randomImg",[633,2677,1034],{"class":1026},[633,2679,2680],{"class":1037}," pcImages[Math.",[633,2682,2683],{"class":1225},"floor",[633,2685,2686],{"class":1037},"(Math.",[633,2688,2689],{"class":1225},"random",[633,2691,2383],{"class":1037},[633,2693,2694],{"class":1026},"*",[633,2696,2399],{"class":1037},[633,2698,2402],{"class":1030},[633,2700,2701],{"class":1037},")];\n",[633,2703,2705],{"class":635,"line":2704},138,[633,2706,2707],{"class":986},"    \u002F\u002F 调用代理函数，直接返回图片流\n",[633,2709,2711,2713,2715,2717],{"class":635,"line":2710},139,[633,2712,1854],{"class":1026},[633,2714,1366],{"class":1026},[633,2716,2019],{"class":1225},[633,2718,2719],{"class":1037},"(randomImg);\n",[633,2721,2723],{"class":635,"line":2722},140,[633,2724,1983],{"class":1037},[633,2726,2728],{"class":635,"line":2727},141,[633,2729,1007],{"emptyLinePlaceholder":16},[633,2731,2733],{"class":635,"line":2732},142,[633,2734,2735],{"class":986},"  \u002F\u002F --- 处理手机壁纸 ---\n",[633,2737,2739,2741,2743,2745,2748],{"class":635,"line":2738},143,[633,2740,2374],{"class":1026},[633,2742,2623],{"class":1037},[633,2744,2626],{"class":1026},[633,2746,2747],{"class":1046}," '\u002Fm-api'",[633,2749,1307],{"class":1037},[633,2751,2753,2755,2758,2760,2762,2764,2766,2768,2770,2772,2774,2776,2778,2780],{"class":635,"line":2752},144,[633,2754,1788],{"class":1026},[633,2756,2757],{"class":1037}," (mobileImages.",[633,2759,2402],{"class":1030},[633,2761,2405],{"class":1026},[633,2763,1181],{"class":1030},[633,2765,2648],{"class":1037},[633,2767,1800],{"class":1026},[633,2769,1347],{"class":1026},[633,2771,2185],{"class":1225},[633,2773,1229],{"class":1037},[633,2775,2659],{"class":1046},[633,2777,2662],{"class":1037},[633,2779,2665],{"class":1030},[633,2781,1266],{"class":1037},[633,2783,2785,2787,2789,2791,2794,2796,2798,2800,2802,2804,2806,2808],{"class":635,"line":2784},145,[633,2786,1640],{"class":1026},[633,2788,2675],{"class":1030},[633,2790,1034],{"class":1026},[633,2792,2793],{"class":1037}," mobileImages[Math.",[633,2795,2683],{"class":1225},[633,2797,2686],{"class":1037},[633,2799,2689],{"class":1225},[633,2801,2383],{"class":1037},[633,2803,2694],{"class":1026},[633,2805,2412],{"class":1037},[633,2807,2402],{"class":1030},[633,2809,2701],{"class":1037},[633,2811,2813],{"class":635,"line":2812},146,[633,2814,2707],{"class":986},[633,2816,2818,2820,2822,2824],{"class":635,"line":2817},147,[633,2819,1854],{"class":1026},[633,2821,1366],{"class":1026},[633,2823,2019],{"class":1225},[633,2825,2719],{"class":1037},[633,2827,2829],{"class":635,"line":2828},148,[633,2830,1983],{"class":1037},[633,2832,2834],{"class":635,"line":2833},149,[633,2835,1007],{"emptyLinePlaceholder":16},[633,2837,2839,2841,2843,2845,2847,2850],{"class":635,"line":2838},150,[633,2840,1561],{"class":1026},[633,2842,1347],{"class":1026},[633,2844,2185],{"class":1225},[633,2846,1229],{"class":1037},[633,2848,2849],{"class":1046},"\"API 正常运行。电脑壁纸请访问 \u002Fapi，手机壁纸请访问 \u002Fm-api\"",[633,2851,2852],{"class":1037},", { \n",[633,2854,2856,2859,2861],{"class":635,"line":2855},151,[633,2857,2858],{"class":1037},"    status: ",[633,2860,2197],{"class":1030},[633,2862,1050],{"class":1037},[633,2864,2866,2869,2872,2874,2877],{"class":635,"line":2865},152,[633,2867,2868],{"class":1037},"    headers: { ",[633,2870,2871],{"class":1046},"\"Content-Type\"",[633,2873,1762],{"class":1037},[633,2875,2876],{"class":1046},"\"text\u002Fhtml;charset=UTF-8\"",[633,2878,2879],{"class":1037}," } \n",[633,2881,2883],{"class":635,"line":2882},153,[633,2884,2885],{"class":1037},"  });\n",[633,2887,2889],{"class":635,"line":2888},154,[633,2890,1588],{"class":1037},[464,2892,2894],{"id":2893},"_54-新增触发规则","5.4 新增触发规则",[426,2896,2897,2900,2913],{},[429,2898,2899],{},"函数发布完成后进入触发规则管理页面，新增自定义匹配规则；",[429,2901,2902,2903,804,2906,2909,2910,2912],{},"匹配路径配置：",[630,2904,2905],{},"^\u002Fapi.*",[630,2907,2908],{},"^\u002Fm-api.*","，匹配域名选择已接入业务站点域名",[630,2911,878],{},"；",[429,2914,2915,2916,2919,2920,2923],{},"保存规则，等待 ",[421,2917,2918],{},"2 ~ 5 min"," 完成全网边缘节点配置同步。\n",[832,2921],{"alt":628,"src":2922},"https:\u002F\u002Fimg.nw177.cn\u002Fblog\u002F2026\u002F07\u002F14\u002F1783959437810.avif",[832,2924],{"alt":628,"src":2925},"https:\u002F\u002Fimg.nw177.cn\u002Fblog\u002F2026\u002F07\u002F14\u002F1783959391699.avif",[457,2927],{},[412,2929,2931],{"id":2930},"_6-全维度功能测试验证","6 全维度功能测试验证",[464,2933,2935],{"id":2934},"_61-基础访问测试","6.1 基础访问测试",[426,2937,2938,2951,2960],{},[429,2939,2940,2941,2944,2945,2947,2948],{},"请求 ",[630,2942,2943],{},"https:\u002F\u002Fapi.img.你的备案域名.com\u002Fapi","，多次刷新随机返回 ",[421,2946,423],{}," 宽屏壁纸二进制图片；\n",[832,2949],{"alt":628,"src":2950},"https:\u002F\u002Fimg.nw177.cn\u002Fblog\u002F2026\u002F07\u002F14\u002F1783959805765.avif",[429,2952,2940,2953,2956,2957],{},[630,2954,2955],{},"https:\u002F\u002Fapi.img.你的备案域名.com\u002Fm-api","，随机返回移动端竖屏适配图片；\n",[832,2958],{"alt":628,"src":2959},"https:\u002F\u002Fimg.nw177.cn\u002Fblog\u002F2026\u002F07\u002F14\u002F1783959897846.avif",[429,2961,2962,2963,2966,2967,2969],{},"非法路由如 ",[630,2964,2965],{},"\u002Ftest"," 访问，接口返回 ",[421,2968,494],{}," 文本提示，路由匹配逻辑正常。",[464,2971,2973],{"id":2972},"_62-缓存机制测试","6.2 缓存机制测试",[426,2975,2976,2983,2989],{},[429,2977,2978,2979,2982],{},"浏览器开发者工具查看响应头，携带 ",[630,2980,2981],{},"Cache-Control: public,max-age=86400"," 缓存标识；",[429,2984,2985,2986,2988],{},"同一区域重复访问同一张图片，",[421,2987,74],{}," 边缘节点命中本地缓存，无额外存储回源请求；",[429,2990,2991,2992,2994],{},"高频调用场景下，持续削减七牛云 \u002F ",[421,2993,487],{}," 对象存储下行流量，长期降低存储计费成本。",[464,2996,2998],{"id":2997},"_63-跨域测试","6.3 跨域测试",[426,3000,3001,3007],{},[429,3002,3003,3004,3006],{},"前端页面通过 fetch、axios 直接调用接口，浏览器无 ",[421,3005,437],{}," 跨域拦截报错；",[429,3008,3009,3012,3013,3016],{},[421,3010,3011],{},"OPTIONS"," 预检请求返回 ",[421,3014,3015],{},"204"," 状态码，完整携带跨域允许头，兼容各类前端请求场景。",[464,3018,3020],{"id":3019},"_64-异常降级测试","6.4 异常降级测试",[426,3022,3023,3026,3032],{},[429,3024,3025],{},"目标图库目录未上传任何图片，接口自动返回配置兜底占位图；",[429,3027,3028,3029,3031],{},"存储 ",[421,3030,444],{}," 配置错误、存储接口网络超时，捕获异常后切换兜底图片；",[429,3033,3028,3034,3036],{},[421,3035,555],{}," 域名失效、图片资源被删除，统一走降级逻辑，页面无空白崩溃。",[457,3038],{},[412,3040,3042],{"id":3041},"_7-当前代码现存缺陷-可落地迭代优化方案","7 当前代码现存缺陷 & 可落地迭代优化方案",[464,3044,3046],{"id":3045},"_71-现有代码局限","7.1 现有代码局限",[426,3048,3049,3055,3065,3068,3075],{},[429,3050,3051,3052,3054],{},"内存单实例缓存短板：",[421,3053,74],{}," 边缘单实例内存缓存不持久，节点扩容、实例重启后缓存数据清空，无分布式持久化缓存支撑；",[429,3056,3057,3058,3061,3062,3064],{},"图片数量上限约束：七牛 list 接口单次限制返回 ",[421,3059,3060],{},"1000"," 条文件，图库图片总量超过 ",[421,3063,3060],{}," 张时无法全量随机抽取；",[429,3066,3067],{},"缺少图片尺寸过滤逻辑：仅通过文件后缀筛选资源，无法根据宽高比例筛选适配图片；",[429,3069,3070,3071,3074],{},"无接口限流防护：未增加 ",[421,3072,3073],{},"IP"," 访问频次限制，恶意高频刷接口会持续消耗存储回源流量；",[429,3076,3077],{},"日志体系简陋：仅基础控制台打印错误信息，无结构化日志上报，无法统计缓存命中率、接口访问量。",[464,3079,3081],{"id":3080},"_72-落地迭代优化方案","7.2 落地迭代优化方案",[426,3083,3084,3091,3097,3100,3107,3113,3116],{},[429,3085,3086,3087,3090],{},"接入 ",[421,3088,3089],{},"EdgeOne KV"," 分布式缓存，将文件列表持久化缓存，减少重复请求存储列表接口；",[429,3092,3093,3094,3096],{},"递归分页拉取存储文件列表，突破单轮 ",[421,3095,3060],{}," 条文件上限，支持上万张图库全量随机；",[429,3098,3099],{},"扩展接口传参能力，支持前端传入宽高比例参数，过滤对应尺寸图片资源；",[429,3101,3102,3103,3106],{},"基于客户端 ",[421,3104,3105],{},"IP + KV"," 存储实现分钟级限流，拦截恶意高频刷接口行为；",[429,3108,3109,3110,3112],{},"对接 ",[421,3111,74],{}," 日志服务，结构化记录缓存命中、回源失败、访问频次等运营数据；",[429,3114,3115],{},"增加动态缓存时长参数，前端可按需传入 max-age 控制边缘缓存有效期；",[429,3117,3118,3119,804,3121,3123,3124,3126],{},"抽离签名逻辑，兼容七牛、",[421,3120,826],{},[421,3122,822],{},"、MinIO 多类 ",[421,3125,487],{}," 标准存储一键切换。",[457,3128],{},[412,3130,3132],{"id":3131},"_8-全文总结","8 全文总结",[464,3134,3136],{"id":3135},"_81-方案适用场景","8.1 方案适用场景",[426,3138,3139,3142,3148,3151],{},[429,3140,3141],{},"Hexo \u002F VitePress 等纯静态博客、个人 \u002F 企业静态站点，需要随机封面、随机壁纸 API；",[429,3143,3144,3145,3147],{},"业务需要 ",[421,3146,423],{},"、移动端两套完全隔离的图片资源池，区分设备展示不同尺寸图片；",[429,3149,3150],{},"无后端服务器，希望依靠边缘计算实现轻量图片接口，降低服务器运维成本；",[429,3152,3153],{},"希望隐藏对象存储真实域名，减少源站流量消耗，控制存储服务计费。",[464,3155,3157],{"id":3156},"_82-整体工程优势","8.2 整体工程优势",[426,3159,3160,3166,3169,3172,3178],{},[429,3161,3162,3163,3165],{},"零后端服务部署，仅依赖 ",[421,3164,74],{}," 边缘函数，服务器运维成本几乎为 0；",[429,3167,3168],{},"全球边缘节点分发图片资源，图片加载速度优于前端直连对象存储；",[429,3170,3171],{},"鉴权密钥存放边缘环境变量，前端无法获取存储地址与鉴权信息，数据安全性更高；",[429,3173,3174,3175,3177],{},"统一封装跨域、缓存、异常降级逻辑，一套代码兼容全部 ",[421,3176,487],{}," 标准对象存储；",[429,3179,3180],{},"完整工程闭环：业务需求 → 方案对比 → 架构设计 → 源码拆解 → 部署实操 → 全维度测试 → 迭代优化，所有代码配置可直接复现落地。",[417,3182,3183],{},"Created with ❤️ by 十三",[3185,3186,3187],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .snhLl, html code.shiki .snhLl{--shiki-default:#22863A;--shiki-default-font-weight:bold;--shiki-dark:#85E89D;--shiki-dark-font-weight:bold}",{"title":628,"searchDepth":642,"depth":642,"links":3189},[3190,3191,3196,3200,3201,3207,3213,3217],{"id":414,"depth":642,"text":415},{"id":461,"depth":642,"text":462,"children":3192},[3193,3194,3195],{"id":466,"depth":648,"text":467},{"id":498,"depth":648,"text":499},{"id":604,"depth":648,"text":605},{"id":616,"depth":642,"text":617,"children":3197},[3198,3199],{"id":620,"depth":648,"text":621},{"id":744,"depth":648,"text":745},{"id":778,"depth":642,"text":779},{"id":852,"depth":642,"text":853,"children":3202},[3203,3204,3205,3206],{"id":856,"depth":648,"text":857},{"id":916,"depth":648,"text":917},{"id":944,"depth":648,"text":945},{"id":2893,"depth":648,"text":2894},{"id":2930,"depth":642,"text":2931,"children":3208},[3209,3210,3211,3212],{"id":2934,"depth":648,"text":2935},{"id":2972,"depth":648,"text":2973},{"id":2997,"depth":648,"text":2998},{"id":3019,"depth":648,"text":3020},{"id":3041,"depth":642,"text":3042,"children":3214},[3215,3216],{"id":3045,"depth":648,"text":3046},{"id":3080,"depth":648,"text":3081},{"id":3131,"depth":642,"text":3132,"children":3218},[3219,3220],{"id":3135,"depth":648,"text":3136},{"id":3156,"depth":648,"text":3157},"md",{"published":72,"author":3223,"image":3224},"十三","https:\u002F\u002Fimg.nw177.cn\u002Fblog\u002F2026\u002F07\u002F14\u002F1783960387193.avif",{"title":71,"description":71},"blog\u002F40-博客搭建\u002F07-腾讯云 EdgeOne 边缘函数实现七牛&S3 随机图床 API",[74,75,67],"EFif_TYZMgHk2MHIO7UjeeYEikAcxXpCG3LjLnKQ_UM",[3230,3231,3232,3233,3234,3235,3236,3237,3238,3239,3240,3241,3242,3243,3244,3245,3246,3247,3248,3249,3250,3251,3252,3253,3254,3255,3256,3257,3258,3259,3260,3261,3262,3263,3264,3265,3266,3267,3268,3269,3270,3271,3272,3273,3274,3275,3276,3277,3278,3279,3280,3281,3282,3283,3284,3285,3286,3287],{"path":6,"title":7,"date":9},{"path":19,"title":20,"date":22},{"path":31,"title":32,"date":34},{"path":42,"title":43,"date":45},{"path":53,"title":54,"date":55},{"path":62,"title":63,"date":64},{"path":70,"title":71,"date":72},{"path":78,"title":79,"date":80},{"path":85,"title":86,"date":87},{"path":92,"title":93,"date":95},{"path":100,"title":101,"date":102},{"path":106,"title":107,"date":108},{"path":112,"title":113,"date":114},{"path":118,"title":119,"date":120},{"path":130,"title":131,"date":132},{"path":139,"title":140,"date":141},{"path":147,"title":148,"date":149},{"path":156,"title":157,"date":158},{"path":165,"title":166,"date":167},{"path":172,"title":173,"date":174},{"path":180,"title":181,"date":182},{"path":186,"title":187,"date":188},{"path":186,"title":192,"date":193},{"path":197,"title":198,"date":199},{"path":204,"title":205,"date":206},{"path":212,"title":213,"date":206},{"path":217,"title":218,"date":206},{"path":223,"title":224,"date":206},{"path":228,"title":229,"date":206},{"path":234,"title":235,"date":206},{"path":239,"title":240,"date":242},{"path":247,"title":248,"date":242},{"path":247,"title":254,"date":242},{"path":247,"title":259,"date":242},{"path":266,"title":267,"date":242},{"path":266,"title":274,"date":242},{"path":278,"title":279,"date":242},{"path":284,"title":285,"date":242},{"path":284,"title":291,"date":242},{"path":284,"title":297,"date":242},{"path":284,"title":301,"date":242},{"path":284,"title":305,"date":242},{"path":284,"title":310,"date":242},{"path":315,"title":316,"date":242},{"path":321,"title":322,"date":242},{"path":321,"title":326,"date":242},{"path":330,"title":331,"date":242},{"path":335,"title":336,"date":242},{"path":342,"title":343,"date":242},{"path":342,"title":348,"date":242},{"path":353,"title":354,"date":242},{"path":361,"title":362,"date":242},{"path":367,"title":368,"date":242},{"path":374,"title":375,"date":242},{"path":380,"title":381,"date":242},{"path":387,"title":388,"date":242},{"path":394,"title":395,"date":242},{"path":380,"title":400,"date":401},1788281982017]