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

news/2024/7/5 20:51: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'

// 注册KoaStatic
app.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 需要替换为自己的oss
const 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文档


http://www.niftyadmin.cn/n/4924514.html

相关文章

一篇文章教会你什么是Linux进程控制

Linux进程控制 进程创建1.fork函数初识1.1那么fork创建子进程时,操作系统都做了什么呢?1.2 父子进程和CPU中的EIP(指令指针)之间存在一定的关系1.3 fork的常规用法有哪些?1.4 fork调用失败的原因有哪些? 2.…

macbook 安装 Git 和 安装 Homebrew

使用MacBook 时,需要拉取代码,我们需要使用到 Git,但 MacBook 中并没安装,这里我们分享一下安装过程。其他方式可查看参考文献中的方法。 一、使用终端直接安装 在新版的 MacBook 中,可以使用终端直接安装 Git&#…

QT开发异常问题

文章目录 前言一、label或edit显示汉字乱码二、发送的QByteArray中文乱码三、QTcpSocket write多次,接收到的是1个包 前言 本篇记录QT开发过程中遇到的异常问题及解决方案,持续更新… 一、label或edit显示汉字乱码 在项目公共头文件中添加以下代码即可…

常量池-JVM(十九)

上篇文章说gc日志以及arthas。 Arthas & GC日志-JVM(十八) 一、常量池 常量池主要放两大类:字面量和符号引用。 字面量就是由字母、数字等构成的字符串或者数值常量。 符号引用主要包含三类常量。 类和接口的全限定名。字段的名称和…

lab7 proxylab

前情提要,如果看了书本,这个lab难度不高,但是如果不看书,难度还是挺高的,并且这个lab会用到cachelab中学到的东西,需要阅读 第十章:系统编程第十一章:网络编程第十二章:…

【腾讯云 Cloud Studio 实战训练营】使用 Cloud Studio 快速构建 Vue + Vite 完成律师 H5 页面

【腾讯云 Cloud Studio 实战训练营】使用 Cloud Studio 快速构建 Vue Vite 完成律师 H5 页面 前言一、基本介绍1.应用场景2.产品优势 二、准备工作1.注册 Cloud Studio2.进入 Vue 预置开发环境 三、使用 Cloud Studio 快速构建 Vue Vite 完成律师 H5 页面1.安装相关依赖包2.主…

SpringBoot+JWT

一、maven坐标 <!-- JWT依赖 --><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency><dependency><groupId>com.auth0</groupId>&…

vite项目中使用@代表根路径

1.配置vite.config.ts import { defineConfig } from vite import vue from vitejs/plugin-vue import path from pathexport default defineConfig({plugins: [vue()],resolve: {alias:{: path.resolve(__dirname, src) }} })2.报错path和__dirname 找不到模块“path”或其相…