写点什么

实现静态资源访问的几种方法

作者:疯狂紫萧
  • 2023-08-09
    北京
  • 本文字数:4410 字

    阅读完需:约 14 分钟

实现静态资源访问的几种方法

什么是静态资源?


静态资源是指在服务器端存储的不会变化的文件,如 HTML、CSS、JavaScript、图片、音频、视频等文件。这些文件一般不包含动态内容,每次请求时返回的内容都是固定的。


为什么要使用静态资源?


  • 提升网站性能:静态资源可以被缓存到客户端,减少了服务器的负载和响应时间,提升了网站的加载速度和性能。

  • 减少网络流量:由于静态资源可以被缓存,客户端只需要在初次请求时下载,后续的请求可以直接使用缓存,减少了网络流量的消耗。

  • 改善用户体验:快速加载的网页能够提供更好的用户体验,降低了用户的等待时间,增加了用户的满意度。

  • 方便管理和维护:静态资源可以独立于服务器端进行管理和维护,更新和替换静态资源也相对简单。


静态资源如何进行存放也有很多中方式,对于如何存放静态资源我们一般会有以下的一些解决方案:

直接编辑放到服务器

这是最简单的一种方法,将静态资源直接编辑放到服务器的指定目录下。当用户访问该服务器时,可以通过 URL 直接访问到这些静态资源。这种方法适用于小型项目或者对访问速度要求不高的场景。

放置到 Nginx 等资源服务器

Nginx 是一个高性能的 HTTP 和反向代理服务器,可以用于静态资源的访问。将静态资源放在 Nginx 服务器上,可以提高访问速度和并发处理能力。通过配置 Nginx 的静态资源目录,可以直接通过 URL 访问这些资源。


  1. 下载安装 nginx

  2. 配置 nginx


location /images {    root /usr/local/nginx/html;}
复制代码


如果把 root 改为 alias,配置需要修改相应配置


location /images {    alias /usr/local/nginx/html/images;}
复制代码


root 和 alias 的区别是 1.root 会把 location 后面的也会加到访问地址里。2.如果 location 路径是以/结尾,则 alias 也必须是以/结尾,而 root 没有要求


  1. 启动 nginx


start nginx 
复制代码


  1. 访问资源在/usr/local/nginx/html 目录下创建一个 images 目录,并在目录下放入一张图片 demo.png 访问图片路径为 http://[ip]/images/demo.png

使用 express、koa 等后端服务

在后端服务器中,可以设置特定的路由来处理静态资源的访问请求。例如,使用 Node.js 的 Express 框架可以使用 express.static 中间件来处理静态资源的请求。


以 koa 为例,使用 koa-static 插件可以通过 url 直接访问静态资源


  1. 安装 koa 以及 koa-static 依赖

  2. 使用 koa 启动一个服务器,配置相应静态资源地址


import Koa from 'koa';import KoaStatic from 'koa-static';import path from 'path';
const app = new Koa();
// public 目录下内容作为静态文件输出const staticPath = './public'
// 注册KoaStaticapp.use(KoaStatic(path.join(__dirname, staticPath)));
const port = process.env.PORT || '8082';app.listen(port, function () { console.log(`服务器运行在http://127.0.0.1:${port}`);});
复制代码


在 public 文件夹中放入 demo.png 就可以通过 http://localhost:8082/demo.png 直接访问图片

资源存放在 CDN

CDN(内容分发网络)是一种分布式网络架构,可以将静态资源缓存到离用户最近的节点上,从而提高资源的访问速度,让用户可以更快的下载资源文件。

CDN 的基本原理

将内容缓存到离用户更近的节点上,使用户能够从就近的节点获取所需的资源,从而减少网络延迟和带宽消耗。下面是 CDN 的基本工作流程:


  • 用户发送请求到目标网站,请求的资源如图片或静态文件。

  • CDN 节点会检查是否有缓存的副本。如果有,CDN 节点将缓存的资源返回给用户;如果没有,进入下一步。

  • CDN 节点向源服务器发起请求,获取源服务器上的资源。

  • 源服务器将资源传输给 CDN 节点。

  • CDN 节点将资源缓存到本地节点,并返回资源给用户。通过将资源缓存到离用户最近的节点,CDN 能够提供更快速和可靠的内容交付,减少了跨越长距离网络的延迟和拥塞。

CDN 的优势

  • CDN 可以分担源服务器的负载。当网站有大量用户访问时,CDN 节点可以缓存并提供静态资源,减轻源服务器的压力,提高网站的稳定性和可扩展性。

  • CDN 可以加速静态资源的加载。将常用的 CSS 和 JavaScript 文件托管到 CDN 上,用户在访问网站时可以从离他们最近的 CDN 节点加载这些文件,加快网页加载速度,提升用户的体验。


以下是几种常见的同步文件到 CDN 的方式:

手动同步

将静态资源上传到 CDN 提供商的控制台,并手动触发同步操作。这种方式适用于静态资源更新频率较低的情况。

自动同步

通过脚本或工具实现自动同步静态资源到 CDN。可以使用 FTP、Rsync 等工具,或者编写脚本进行定时同步。这种方式适用于静态资源更新频率较高的场景。1.使用 rsync 工具进行同步,rsync 是一个强大的文件同步工具,可以用于在本地和远程服务器之间同步文件。


基本语法如下:


  rsync [OPTION]... SRC [SRC]... DEST
复制代码


其中,SRC 是源文件或目录的路径,DEST 是目标文件或目录的路径。


以下是一些常用的 rsync 选项:


  • -a:归档模式,保持文件的所有属性,包括权限、所有者和组、时间戳等。

  • -v:显示详细输出,可以查看文件同步的进度和结果。

  • -z:启用压缩传输,可以加快网络传输速度。

  • --delete:删除目标目录中不存在于源目录中的文件。

  • --exclude:排除指定的文件或目录,可以使用通配符。


以下是一些示例用法:


  • 将本地目录/path/to/source同步到远程服务器的/path/to/destination目录:


  rsync -avz /path/to/source remoteuser@remotehost:/path/to/destination
复制代码


  • 同步文件时排除某些文件或目录:


  rsync -avz --exclude 'file.txt' /path/to/source remoteuser@remotehost:/path/to/destination
复制代码


rsync 需要在本地和远程服务器上都安装并可用。另外,确保在使用 rsync 时,你有足够的权限来访问源和目标文件。


  1. 使用 scp 命令进行同步,SCP(Secure Copy)是一种在本地主机和远程主机之间进行安全文件传输的命令行工具。它基于 SSH 协议,提供了加密的数据传输。


使用 SCP 进行文件传输的基本语法如下:


scp [选项] [源文件路径] [目标路径]
复制代码


其中,[选项]是可选的,可以用于指定一些参数,如连接端口、指定密钥等。[源文件路径]是要传输的文件或目录的路径,可以是本地路径或远程路径。[目标路径]是文件传输的目标路径,可以是本地路径或远程路径。


以下是一些常用的 SCP 命令示例:


  • 从本地主机拷贝文件到远程主机:


scp /path/to/local/file username@remote:/path/to/remote/directory
复制代码


  • 从本地主机拷贝整个目录到远程主机:


scp -r /path/to/local/directory username@remote:/path/to/remote/directory
复制代码


在执行 SCP 命令时,可能需要输入密码或提供密钥进行身份验证。如果远程主机使用非默认的 SSH 端口,可以使用-P选项指定端口号。

基于版本控制系统的同步

将静态资源放在版本控制系统(如 Gitlab)中,并通过钩子脚本实现自动同步到 CDN。每次提交代码时,自动触发同步操作。这种方式适用于团队协作开发,需要保持静态资源与代码同步的情况。


在 Gitlab 中使用 ci 同步文件:


  1. 安装 Gitlab Runner

  2. 执行注册 Runner 注册,根据提示输入 token 等内容,相关内容在 gitlab 网站中可以看到


gitlab-runner register
复制代码



  1. 在 GitLab 仓库中创建一个名为.gitlab-ci.yml 的文件,定义一个名为 job 的任务。例如:


job:  script:    - sh script.sh
复制代码


script.sh 中可以进行同步文件


rsync -av -e ssh ./ root@ip:/data/
复制代码


  1. 提交并推送.gitlab-ci.yml 文件到你的 GitLab 仓库。

  2. 当你提交代码时,GitLab 将会自动执行定义的任务,并执行你的 shell 脚本。


注意,你需要确保你的 GitLab 仓库已经启用了 CI/CD 功能,并且你的 GitLab Runner 已经正确配置和连接到你的仓库。

API 同步

一些 CDN 提供商提供 API 接口,可以通过编写程序调用 API 实现静态资源的同步。通过 API 可以实现更加灵活和精细化的资源同步操作。比如在阿里云使用 CDN 加速 OSS 访问,使用 oss 的 api 进行文件的同步


main.ts


import fs from 'fs';import path from 'path';import OSSClient from './OSSClient';
const ProjectName = require('./package.json').name;
// bucket 需要替换为自己的ossconst ossClient = new OSSClient('bucket');

function main() { const dir = './lib'; const list = []; getIndexOfPathByDeep(list, dir, ''); const promiseList = list.map(url => { const file = fs.readFileSync(url); return ossClient.client.put(ProjectName + '/' +url, file, { 'Content-Encoding': 'gzip' }); });
Promise.all(promiseList).then(list => { console.log('async oss complate'); }, err => { console.log('error====='); console.log(err); })}
function getIndexOfPathByDeep(dirList, dir, curDir) { let curPath = path.join(dir, curDir); // 搜索到文件,停止 if(fs.statSync(curPath).isDirectory()) { let lists = fs.readdirSync(curPath); lists.forEach(childDir => getIndexOfPathByDeep(dirList, curPath, childDir)); } else { dirList.push(curPath); }}
main();
复制代码


OSSClient.ts




import OSS from 'ali-oss';
//默认配置const DEFAULT = { region: 'oss-cn-beijing', accessKeyId: 'accessKeyId', accessKeySecret: 'accessKeySecret', secure: true,};/** * 文件上传下载类,使用的是OSS的SDK */class OSSClient { constructor(bucket: string, opts: OSS.Options = DEFAULT) { this.Options = Object.assign({ bucket }, opts); this.Host = bucket; //初始化 this.client = new OSS(this.Options); } client: OSS; Options: OSS.Options; Host: string;
async getFileName(file: File) { const mime = file.name.substring(file.name.lastIndexOf('.')); const filename = Date.now() + Math.round(Math.random() * 1000); return `file/${filename}${mime}`; }
/** * 简单的上传文件,小于100MB * @param file 文件对象 * @param opts 参数 * @returns 文件结果对象 */ async upload(file: File, opts: OSS.PutObjectOptions = {}) { const fileName = await this.getFileName(file); opts.mime = file.type.includes('image') ? 'image/jpg' : file.type; const result = await this.client.put(fileName, file, opts); return { uid: result.name, key: result.name, url: this.Host + fileName, downloadUrl: this.client.signatureUrl(result.name), name: result.name, textUrl: this.Host + fileName, }; }}export default OSSClient;
复制代码


以上是实现静态资源访问的几种方法,包括直接编辑放到服务器、koa 搭建静态服务器、单独放在 Nginx 服务器以及放在 CDN 并同步文件的几种方式。每种方法都有其适用的场景和优势,读者可以根据自己项目的需求选择合适的方法。在实际应用中,可以根据项目的规模、访问量和资源更新频率等因素综合考虑,选择最合适的静态资源访问方式

参考

阿里云oss文档

Koa文档

发布于: 刚刚阅读数: 5
用户头像

疯狂紫萧

关注

资深前端,其他技术都又涉猎。 2023-07-26 加入

还未添加个人简介

评论

发布
暂无评论
实现静态资源访问的几种方法_前端_疯狂紫萧_InfoQ写作社区