一、场景和目标:
      用户上传一个包含 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自解析生成相对路径的更多相关文章

  1. 国内静态文件CDN服务介绍 国内js公共库

    国内静态文件CDN服务介绍 新浪SAE  介绍页 文件页 百度云 介绍页 七牛云存储介绍页 优势,可以提交没有的库,支持https,但证书不可信. 又拍云 介绍页 建议使用阿里云OSS自己上传所需文件 ...

  2. 【推荐】开放静态文件 CDN服务staticfile.org

    虽然国内外有很多类似的服务器,比如最初的google ajax api,还有后来的sae,百度等都有提供,但是也都有不同的弊端,比如国内访问速度慢.提供的静态文件不全等...staticfile有望解 ...

  3. Django——3 模板路径 模板变量 常用过滤器 静态文件的使用

    Django 模板路径 模板变量 过滤器 静态文件的加载 模板的路径,有两种方法来使用 设置一个总的templates在大项目外面,然后在sittings的TEMPLATES中声明 在每一个APP中创 ...

  4. javaweb项目springmvc,和tomcat对静态文件的处理

    1.激活Tomcat的defaultServlet来处理静态文件,web.xml配置 <servlet-mapping> <servlet-name>default</s ...

  5. 静态文件与APP

    目录 静态文件的配置和使用 什么是静态文件? 为什么使用静态文件 如何配置,使用静态文件 静态文件相关(动态配置) app创建预注册 app指什么? 创建一个APP 注册app app文件作用 app ...

  6. [Django框架 - 静态文件配置、request对象方法初识、 pycharm链接数据库、ORM实操增删改查、django请求生命周期]

    [Django框架 - 静态文件配置.request对象方法初识. pycharm链接数据库.ORM实操增删改查.django请求生命周期] 我们将html文件默认都放在templates文件夹下 将 ...

  7. Django学习之十: staticfile 静态文件

    目录 Django学习之十: staticfile 静态文件 理解阐述 静态文件 Django对静态文件的处理 其它方面 总结 Django学习之十: staticfile 静态文件 理解阐述     ...

  8. Django 配置文件settings注解(含静态文件和上传文件配置)

    基于Django1.11配置文件settings.py import os import sys # Build paths inside the project like this: os.path ...

  9. django加载静态文件

    在一个网页中,不仅仅只有一个 html 骨架,还需要 css 样式文件. js 执行文件以及一些图片等,因此在 DTL 中加载静态文件是一个必须要解决的问题.在 DTL 中,使用 static 标签来 ...

随机推荐

  1. KaTex语法说明

    参考链接: https://katex.org/docs/supported.html https://github.com/KaTeX/KaTeX/blob/master/docs/supporte ...

  2. jquerymobile tap事件被触发两次

    首先介绍一下这个问题出现的背景:我在写网站时想要一套代码兼容手机端和pc端,所以用了jquery和jquery mobile,点击事件用的jquerymobile tap事件,但是在移动端测试时出现点 ...

  3. singleton单例模式小结

    1.饿汉模式 public class SingletonEntity2 { // 在类加载的时候创建对象:饿汉模式 public static SingletonEntity2 obj = new ...

  4. Cookie、Session、Token那点事儿和前后端分离之JWT用户认证

    (两篇文章转自:https://www.jianshu.com/p/bd1be47a16c1:https://www.jianshu.com/p/180a870a308a) 什么是Cookie? Co ...

  5. celery timeout的拦截

    0X01 场景 celery任务超时报错,想查看是传入哪一类数据运行时导致的超时(哪一个插件),但是该报错难以拦截. [2019-06-30 17:23:21,070: ERROR/MainProce ...

  6. Kylin介绍 (很有用)

    转:http://blog.csdn.net/yu616568/article/details/48103415 Kylin是ebay开发的一套OLAP系统,与Mondrian不同的是,它是一个MOL ...

  7. VIM--保存和退出等命令

    在 Linux 中使用 vim 时,输入 vim xxx.file 按 ESC,左下角就可以进行输入 :w 保存但不退出 :wq 保存并退出 :q 退出 :q! 强制退出,不保存 :e! 放弃所有修改 ...

  8. Navicat连接Oracle报ORA-12737错误

    替换oci.dll 文件分享百度网盘:链接:https://pan.baidu.com/s/1wayojGlKcgdMRZTvBqAUgw 密码:3d6j 把下载的文件放到Navicat文件夹里,然后 ...

  9. 057_统计 Linux 进程相关数量信息

    #!/bin/bashrunning=0sleeping=0stoped=0zombie=0 #在 proc 目录下所有以数字开始的都是当前计算机正在运行的进程的进程 PID#每个 PID 编号的目录 ...

  10. java大文件上传解决方案

    最近遇见一个需要上传百兆大文件的需求,调研了七牛和腾讯云的切片分段上传功能,因此在此整理前端大文件上传相关功能的实现. 在某些业务中,大文件上传是一个比较重要的交互场景,如上传入库比较大的Excel表 ...