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

什么是静态资源?

静态资源是指在服务器端存储的不会变化的文件,如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文档

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/65987.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Django实现音乐网站 ⑻

使用Python Django框架制作一个音乐网站, 本篇主要是后台对单曲原有功能的基础上进行部分功能实现和显示优化。 目录 新增编辑 歌手下拉显示修改 设置歌曲时长 安装eyed3库 获取mp3时长 歌曲时长字段修改 重写save方法 增加歌手单曲数量 查询歌手单曲数量 …

【Redis】Spring/SpringBoot 操作 Redis Java客户端

目录 操作 Redis Java客户端SpringBoot 操作Redis 步骤 操作 Redis Java客户端 1.Jedis 2.Lettuce(主流) <-Spring Data Redis SpringBoot 操作Redis 步骤 1.添加Redis 驱动依赖 2.设置Redis 连接信息 spring.redis.database0 spring.redis.port6379 spring.redis.host…

springboot工程使用阿里云OSS传输文件

在application.yml文件中引入对应的配置&#xff0c;一个是对应的节点&#xff0c;两个是密钥和账号&#xff0c;还有一个是对应文件的名称&#xff1b; 采用这样方式进行解耦&#xff0c;便于后期修改。 然后需要设置一个properties类&#xff0c;去读对应的配置信息 用到了…

TCP的四次挥手与TCP状态转换

文章目录 四次挥手场景步骤TCP状态转换 四次挥手场景 TCP客户端与服务器断开连接的时候&#xff0c;在程序中使用close()函数&#xff0c;会使用TCP协议四次挥手。 客户端和服务端都可以主动发起。 因TCP连接时候是双向的&#xff0c;所以断开的时候也是双向的。 步骤 三次…

(九)人工智能应用--深度学习原理与实战--前馈神经网络实现MNST手写数字识别

目标: 识别手写体的数字,如图所示: 学习内容: 1、掌握MNIST数据集的加载和查看方法 2、熟练掌握Keras建立前馈神经网络的步骤【重点】 3、掌握模型的编译及拟合方法的使用,理解参数含义【重点】 4、掌握模型的评估方法 5、掌握模型的预测方法 6、掌握自定义图片的处理与预测 …

网络安全【黑客】面试题汇总

前言 一眨眼2023年已经过去一大半&#xff0c;不知道大家有没有找到心仪的工作。作为一个安全老鸟&#xff0c;工作这么多年&#xff0c;面试过很多人也出过很多面试题目&#xff0c;也在网上收集了各类关于渗透面试题目&#xff0c;里面有我对一些问题的见解&#xff0c;希望…

信创麒麟操作系统卸载docker,并分别用在线、yum、rpm三种方式安装信创的docker

备注&#xff1a;操作前建议对机器打快照备份&#xff0c;或者备份好数据&#xff0c;如未使用&#xff0c;第一次部署的情况可直接操作 一、卸载DataEase自带的docker # 停止服务 service dataease stop# 删除 docker 可执行文件 rm -f /usr/bin/containerd-shim-runc-v2 r…

04-5_Qt 5.9 C++开发指南_QComboBox和QPlainTextEdit

文章目录 1. 实例功能概述2. 源码2.1 可视化UI设计2.2 widget.h2.3 widget.cpp 1. 实例功能概述 QComboBox 是下拉列表框组件类&#xff0c;它提供一个下拉列表供用户选择&#xff0c;也可以直接当作一个QLineEdit 用作输入。OComboBox 除了显示可见下拉列表外&#xff0c;每个…

【EI复现】梯级水光互补系统最大化可消纳电量期望短期优化调度模型(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

事件循环原理

事件循环 浏览器的进程模型 何为进程&#xff1f; 程序运行需要有它自己专属的内存空间&#xff0c;可以把这块内存空间简单的理解为进程 每个应用至少有一个进程&#xff0c;进程之间相互独立&#xff0c;即使要通信&#xff0c;也需要双方同意。 何为线程&#xff1f; 有…

【雕爷学编程】 MicroPython动手做(35)——体验小游戏3

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…

HDFS中的Trash垃圾桶回收机制

Trash垃圾桶回收机制 文件系统垃圾桶背景功能概述Trash Checkpoint Trash功能开启关闭HDFS集群修改core-site.xml删除文件到trash删除文件跳过从trash中恢复文件清空trash 文件系统垃圾桶背景 回收站&#xff08;垃圾桶&#xff09;是windows操作系统里的一个系统文件夹&#…

sql刷题

文章目录 section A1 各部门工资最高的员工&#xff08;难度&#xff1a;中等&#xff09;2 换座位&#xff08;难度&#xff1a;中等&#xff09;3 分数排名&#xff08;难度&#xff1a;中等&#xff09;4 连续出现的数字&#xff08;难度&#xff1a;中等&#xff09;5 树节…

谈谈对Spring MVC的理解

问题分析&#xff1a; SpringMVC 是一种基于 Java 语言开发&#xff0c;实现了 Web MVC 设计模式&#xff0c;请求驱动类型 的轻量级 Web 框架。 SpringMVC采用了 MVC 架构模式的思想&#xff0c;通过把 Model&#xff0c;View&#xff0c;Controller 分离&#xff0c;将 Web 层…

postgresql|数据库|角色(用户)管理工作---授权和去权以及usage和select两种权限的区别

前言&#xff1a; postgresql做为一个比较复杂的关系型的重型数据库&#xff0c;不管是安装部署&#xff0c;还是后期的运行维护&#xff0c;都还是有比较多的细节问题需要引起关注。 例如&#xff0c;用户权限的合理分配&#xff0c;那么&#xff0c;什么是权限的合理分配呢…

边写代码边学习之numpy

1. numpy.matmul() 用法 matmul() 用于计算两个数组的矩阵乘积。示例如下 def matmul_test():array1 np.array([[[1.0, 3], [1, 1], [2, 3]]])array2 np.array([[2, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0],[1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0], ])result np.matmul(array1, …

用html+javascript打造公文一键排版系统15:一键删除所有空格

现在我们来实现一键删除所有空格的功能。 一、使用原有的代码来实现&#xff0c;测试效果并不理想 在这之前我们已经为String对象编写了一个使用正则表达式来删除所有空格的方法&#xff1a; //功能&#xff1a;删除字符串中的所有空格 //记录&#xff1a;20230726创建 Stri…

Day 25 C++ queue 容器(队列)

文章目录 queue 基本概念定义注意基本概念队头&#xff08;Front&#xff09;——指向队列中最早添加的元素的位置。队尾&#xff08;Rear&#xff09;——指向队列中最后添加的元素的位置。入队&#xff08;Enqueue&#xff09;——将元素添加到队尾。出队&#xff08;Dequeue…

TCP三次握手四次断开

一、了解TCP &#x1f345;TCP &#xff1a;传输控制协议&#xff0c;是一种面向连接的可靠的传输协议。 什么是可靠的传输协议&#xff1f;如何保障可靠传输&#xff1f; 保证可靠性&#xff1a; 1.确认机制 2.重传输机制什么是面向连接&#xff1f;如何保障面…

zookeeper --- 高级篇

一、zookeeper 事件监听机制 1.1、watcher概念 zookeeper提供了数据的发布/订阅功能&#xff0c;多个订阅者可同时监听某一特定主题对象&#xff0c;当该主题对象的自身状态发生变化时(例如节点内容改变、节点下的子节点列表改变等)&#xff0c;会实时、主动通知所有订阅者 …