静态文件cdn自解析生成相对路径
一、场景和目标:
用户上传一个包含 index.html 的静态资源压缩包,资源内所有文件都是相互依赖的,不需要用户对内部文件内容做任何特殊处理,仅通过服务端逻辑处理达到用户访问 http://xxx.xxx/guid/index.html 时就可以得到这个资源的所有数据并正常浏览。
二、技术:
nodejs、express
npm 包:decompress、request、crypto、pinyin
三、思路:
a、上传解析:
对每一个资源生成唯一的 guid,将用户上传的压缩包解压之后,按照解压完成的文件的目录结构以 guid 为初始前缀拼接路径,这样就可以保证所有文件在 cdn 的相对路径就是文件在原始资源包中的相对路径,然后对文件信息和路径进行存储即可。
b、访问index:
用户首先要获得静态资源的列表,其实就是获得所有静态资源的 guid 列表,或者说是静态资源的唯一 id,这个唯一 id 都会对应一个唯一的 guid,当用户访问 [http://xxx.xxx/:id/ | http://xxx.xxx/:id/index | http://xxx.xxx/:id/index.html] 这些路径时,配置中间件,通过 id 处理中间件去服务端获取此 id 对应的 guid 值,然后拼接 index 文件的 cdn 地址,pipe 回浏览器。
c、获取相对路径资源:
当浏览器拿到 index 文件之后,index 文件中的所有依赖都会以 index 文件的前置路径为基准进行获取,也就是说如果现在依赖一个 index.js 文件,这个文件相对于 index.html 文件的路径是/scripts/index.js,那么服务端就会收到一个请求,这个请求的 url 是 http://xxx.xxx/:id/scripts/index.js,这里为了保证请求的正确性,并没有在 index 文件 guid 解析完成之后向 cookie 中存储 guid,而是所有静态资源的请求都去获取新的 guid 值,拿到 guid 之后,就可以通过相对路径拼合出此静态文件在 cdn 中存储的位置路径信息,路径信息拼合好之后,使用 request 包的 pipe 方法直接相应给用户 cdn 中静态资源的数据即可。
通过上面三个步骤,就可以实现上面场景中所描述的要求,是此类问题的一种处理方式。
四、遇到的问题:
a、数据存储
由于项目是以静态资源为主的,因此要求服务端部分要轻量,因此在服务端处理逻辑中未加入任何数据库、公有配置、权限、登陆等功能,所有的数据交互全部通过主项目的对外接口进行接入,保证了项目中服务端部分只有纯逻辑,代码量也比较少,是一种不错的选择。
b、确定所有目标文件位置
在这里遇到一个问题就是,如果用户上传的压缩包中存在一些不合法的或者不需要使用的额外文件怎么办,理论来说在服务端无法确定哪些文件是需要被引用的,但是根据上传规定和要求,资源包内最外层一定要有一个 index.html 文件,那么就可以通过 index 文件进行处理,只保留和 index 同层及其下层的文件,这样可以保证 index 文件一定是在最外层的,其余文件全部忽略,保证只存储有用的资源。
c、三方npm包解压压缩包时中文问题
刚开始使用的一个 npm 包解压之后中文是乱码,上传 cdn 后找不到此文件,后面对乱码文件的路径进行 encode,然后可以在 cdn找到此文件了,但是再向用户 pipe 时出现问题,被 encode 的文件无法 pipe,虽然文件请求返回了200,但是资源数据就是拿不到,很惆怅,在尝试了五六个包之后,终于找到一个可以对中文进行正常解压的包,算是先解决了乱码问题,可encode 后无法向用户 pipe 的问题还是没有解决,于是想到了下面的方式。
d、阿里云cdn向用户pipe文件时被encode的文件回传失败
由于 encode 的文件回传失败,直接存储中文也不是很好,因此想到将中文转换为拼音的办法,就是在读取资源包中的文件并拼合其 cdn 路径时,对路径中的中文进行转换,转为拼音,然后用户访问这些文件时对访问的 url 也进行拼音转换,这样就确保了数据的正确性同时也避免在数据库和 cdn 中存储中文导致的各种问题。
五、流程图:

六、示例:
假设现在上传了个资源包,解压后目录结构长下面这个样子:
/yyy
/zzz
zzz.html
/xxx
index.html
/js
index.js
/css
index.css
/images
index.png
生成的 guid 长后面这个样子:abcdefghijklmnopqrstuvwzyx。
那么这些资源的 cdn 地址就是下面的样子:
/abcdefghijklmnopqrstuvwzyx/index.html
/abcdefghijklmnopqrstuvwzyx/js/index.js
/abcdefghijklmnopqrstuvwzyx/css/index.css
/abcdefghijklmnopqrstuvwzyx/images/index.png
在 views 中将会存在一个名为abcdefghijklmnopqrstuvwzyx的文件夹,里面静静的躺着 index.html 文件等待被用户访问。
七、结束。
静态文件cdn自解析生成相对路径的更多相关文章
- 国内静态文件CDN服务介绍 国内js公共库
国内静态文件CDN服务介绍 新浪SAE 介绍页 文件页 百度云 介绍页 七牛云存储介绍页 优势,可以提交没有的库,支持https,但证书不可信. 又拍云 介绍页 建议使用阿里云OSS自己上传所需文件 ...
- 【推荐】开放静态文件 CDN服务staticfile.org
虽然国内外有很多类似的服务器,比如最初的google ajax api,还有后来的sae,百度等都有提供,但是也都有不同的弊端,比如国内访问速度慢.提供的静态文件不全等...staticfile有望解 ...
- Django——3 模板路径 模板变量 常用过滤器 静态文件的使用
Django 模板路径 模板变量 过滤器 静态文件的加载 模板的路径,有两种方法来使用 设置一个总的templates在大项目外面,然后在sittings的TEMPLATES中声明 在每一个APP中创 ...
- javaweb项目springmvc,和tomcat对静态文件的处理
1.激活Tomcat的defaultServlet来处理静态文件,web.xml配置 <servlet-mapping> <servlet-name>default</s ...
- 静态文件与APP
目录 静态文件的配置和使用 什么是静态文件? 为什么使用静态文件 如何配置,使用静态文件 静态文件相关(动态配置) app创建预注册 app指什么? 创建一个APP 注册app app文件作用 app ...
- [Django框架 - 静态文件配置、request对象方法初识、 pycharm链接数据库、ORM实操增删改查、django请求生命周期]
[Django框架 - 静态文件配置.request对象方法初识. pycharm链接数据库.ORM实操增删改查.django请求生命周期] 我们将html文件默认都放在templates文件夹下 将 ...
- Django学习之十: staticfile 静态文件
目录 Django学习之十: staticfile 静态文件 理解阐述 静态文件 Django对静态文件的处理 其它方面 总结 Django学习之十: staticfile 静态文件 理解阐述 ...
- Django 配置文件settings注解(含静态文件和上传文件配置)
基于Django1.11配置文件settings.py import os import sys # Build paths inside the project like this: os.path ...
- django加载静态文件
在一个网页中,不仅仅只有一个 html 骨架,还需要 css 样式文件. js 执行文件以及一些图片等,因此在 DTL 中加载静态文件是一个必须要解决的问题.在 DTL 中,使用 static 标签来 ...
随机推荐
- 牛客练习赛48 C 小w的糖果 (数学,多项式,差分)
牛客练习赛48 C 小w的糖果 (数学,多项式) 链接:https://ac.nowcoder.com/acm/contest/923/C来源:牛客网 题目描述 小w和他的两位队友teito.toki ...
- 关于zsh-autosuggestions插件导致粘贴内容很慢的问题
zsh开启autosuggestions 插件的时候,在终端中粘贴大量的内容的时候,会粘贴的很慢,基本上是一个字符一个字符的粘贴的. 解决方案 在.zshrc文件中配置以下内容: # This spe ...
- k8s的容器编排
1.K8S是如何对容器编排? 在K8S集群中,容器并非最小的单位,K8S集群中最小的调度单位是Pod,容器则被封装在Pod之中.由此可知,一个容器或多个容器可以同属于在一个Pod之中. 2.Pod是怎 ...
- python(列表及列表的相关操作、元组和range)
1.什么是列表 列表是一个课表的数据类型 列表有[]来表示,每一项元素用逗号隔开,列表什么都能装.是能装对象的对象. 列表可以装大量数据. 2.列表的索引和切片 列表和字符串一样,也有索引和切片.只不 ...
- 神经网络(3)---如何表示hypothesis,如何表示我们的model
大脑中的神经元 我们的大脑都充满了上图所示的神经元,神经元有一个细胞体(cell body),还有一些input wires,专业词汇叫做树突(dendrite),它们从其它地方接收输入信息,神经元还 ...
- Mac下mysql出现错误:ERROR 1055 (42000)
问题原因: ONLY_FULL_GROUP_BY的意思是:对于GROUP BY聚合操作,如果在SELECT中的列,没有在GROUP BY中出现,那么这个SQL是不合法的,因为列不在GROUP BY从句 ...
- 14 Vue列表渲染
列表渲染 用 v-for 把一个数组对应为一组元素(for循环) 我们可以用 v-for 指令基于一个数组来渲染一个列表. v-for 指令需要使用 item in items 形式的特殊语法, 其中 ...
- [NOIP 2018]旅行
题目链接 题意简介:现有一个图,小Y要把它走完,每个点只去一次,路径字典序最小. 分析:这道题我认为很重要的一个点就是它的数据范围.它只有两种 m=n-1 或 m=n.我们先考虑第一种:m=n-1也就 ...
- MD5加密的引用
使用MD5 加密时 需要在后台代码中添加using System.Security.Cryptography; 引用 //MD5加密密码 byte[] a = MD5.Create().Compute ...
- 【转】harbor仓库高可用集群部署说明
之前介绍Harbor私有仓库的安装和使用,这里重点说下Harbor高可用集群方案的部署,目前主要有两种主流的Harbor高可用集群方案:1)双主复制:2)多harbor实例共享后端存储. 一.Harb ...