一、场景和目标:
      用户上传一个包含 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. 云计算(8)--MapReduce如何处理fault

    一些常见的故障 NM周期性的给RM发送heartbeats,如果RM发现server fails,则它会让所有与这个server有关的AM知道,让受影响的job的AM采取一些action,重新分配它的 ...

  2. DateTime函数

    一.初始化: DateTime dt = , , ); DateTime dt1 = DateTime.Now; DateTime dt2 = DateTime.Today; DateTime dt3 ...

  3. Prometheus+Grafana监控

    什么是Prometheus? Prometheus是由SoundCloud开发的开源监控报警系统和时序列数据库(TSDB).Prometheus使用Go语言开发,是Google BorgMon监控系统 ...

  4. Spring MVC 学习笔记(二)

    6. 视图和视图解析器  ❤  Spring MVC如何解析视图                                  • 请求处理方法执行完成后,最终返回一个ModelAndView对象 ...

  5. vscode源码编译疑难问题

    最近把原来老的源码merge到了新的1.15版本源码,以前的依赖问题会导致各种错误,Loading "gc-signals" failed啦,Error: %1 is not a ...

  6. Python十大经典排序算法

    现在很多的事情都可以用算法来解决,在编程上,算法有着很重要的地位,将算法用函数封装起来,使程序能更好的调用,不需要反复编写. Python十大经典算法: 一.插入排序 1.算法思想 从第二个元素开始和 ...

  7. Python中字符串与字节之间相互转换

    Python中字符串与字节之间相互转换 ​ a = b"Hello, world!" # bytes object b = "Hello, world!" # ...

  8. linux系列(二十):find命令

    1.命令格式 find pathname -options [-print -exec -ok ...] 2.命令功能 用于在文件树种查找文件,并作出相应的处理 3.命令参数 pathname: fi ...

  9. 贾扬清牛人(zz)

    贾扬清加入阿里巴巴后,能否诞生出他的第三个世界级杰作? 文 / 华商韬略 张凌云  本文转载,著作权归原作者所有   贾扬清加入阿里巴巴后,能否诞生出他的第三个世界级杰作? 2017年1月11日,美国 ...

  10. Codechef July Challenge 2019 Division 1题解

    题面 \(CIRMERGE\) 破环成链搞个裸的区间\(dp\)就行了 //quming #include<bits/stdc++.h> #define R register #defin ...