静的リソースへのアクセスを実装するためのいくつかの方法

静的リソースとは何ですか?

静的リソースとは、HTML、CSS、JavaScript、画像、オーディオ、ビデオ、その他のファイルなど、サーバー側に保存される変更されないファイルを指します。通常、これらのファイルには動的コンテンツは含まれず、返されるコンテンツはリクエストごとに固定されています。

なぜ静的リソースを使用するのでしょうか?

  • Web サイトのパフォーマンスの向上: 静的リソースをクライアントにキャッシュできるため、サーバーの負荷と応答時間が軽減され、Web サイトの読み込み速度とパフォーマンスが向上します。
  • ネットワーク トラフィックの削減: 静的リソースはキャッシュできるため、クライアントは最初のリクエストでのみダウンロードする必要があり、後続のリクエストではキャッシュを直接使用できるため、ネットワーク トラフィックの消費が削減されます。
  • ユーザー エクスペリエンスの向上: Web ページの読み込みが速いと、ユーザー エクスペリエンスが向上し、ユーザーの待ち時間が短縮され、ユーザーの満足度が向上します。
  • 便利な管理とメンテナンス: 静的リソースはサーバーから独立して管理および保守でき、静的リソースの更新と置換は比較的簡単です。

静的リソースを保存するにはさまざまな方法がありますが、静的リソースを保存する方法には通常、次のソリューションがあります。

直接編集してサーバーに置く

これは最も簡単な方法で、静的リソースを直接編集し、サーバーの指定されたディレクトリに配置します。ユーザーがサーバーにアクセスすると、URL を通じてこれらの静的リソースに直接アクセスできます。この方法は、小規模なプロジェクトやアクセス速度が高くないシナリオに適しています。

Nginxなどのリソースサーバーに配置します。

Nginx は、静的リソースへのアクセスに使用できる高性能 HTTP およびリバース プロキシ サーバーです。Nginx サーバーに静的リソースを配置すると、アクセス速度と同時処理能力が向上します。Nginx の静的リソース ディレクトリを構成すると、URL を通じてこれらのリソースに直接アクセスできるようになります。

  1. nginxをダウンロードしてインストールします
  2. nginxの設定
bash复制代码location /images {
    root /usr/local/nginx/html;
}

ルートをエイリアスに変更する場合は、それに応じて構成を変更する必要があります。

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

ルートとエイリアスの違いは、1. ルートはアクセス アドレスに次の場所を追加します。2. ロケーション パスが / で終わる場合、エイリアスも / で終わる必要がありますが、root には要件はありません。

  1. nginxを起動する
sql复制代码start nginx 

4. リソースにアクセスするには、/usr/local/nginx/html ディレクトリに image ディレクトリを作成し、そのディレクトリに画像のデモ.png を配置します。画像にアクセスするためのパスは http://[ip]/images/ です。デモ.png。

Express、koa、その他のバックエンド サービスを使用する

バックエンド サーバーでは、静的リソースへのアクセス要求を処理するために特定のルートを設定できます。たとえば、Node.js を使用する Express フレームワークは、express.static ミドルウェアを使用して静的リソースのリクエストを処理できます。

koa を例に挙げると、koa-static プラグインを使用すると、URL を通じて静的リソースに直接アクセスできます。

  1. koa および koa-static 依存関係をインストールする
  2. koa を使用してサーバーを起動し、対応する静的リソース アドレスを設定します。
javascript复制代码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}`);
});

demo.png をパブリック フォルダーに置くと、http://localhost:8082/demo.png を通じて画像に直接アクセスできます。

リソースは CDN に保存されます

CDN (コンテンツ配信ネットワーク) は、静的リソースをユーザーに最も近いノードにキャッシュできる分散ネットワーク アーキテクチャです。これにより、リソースへのアクセス速度が向上し、ユーザーがリソース ファイルをより速くダウンロードできるようになります。

CDNの基本原則

ユーザーに近いノードにコンテンツをキャッシュすると、ユーザーは近くのノードから必要なリソースを取得できるようになり、ネットワークの遅延と帯域幅の消費が削減されます。CDN の基本的なワークフローは次のとおりです。

  • ユーザーはターゲット Web サイトにリクエストを送信し、画像や静的ファイルなどのリソースを要求します。
  • CDN ノードは、キャッシュされたコピーがあるかどうかを確認します。存在する場合、CDN ノードはキャッシュされたリソースをユーザーに返します。存在しない場合は、次のステップに進みます。
  • CDN ノードは、オリジン サーバー上のリソースを取得するためにオリジン サーバーへのリクエストを開始します。
  • オリジンサーバーはリソースを CDN ノードに転送します。
  • CDN ノードはリソースをローカル ノードにキャッシュし、ユーザーにリソースを返します。CDN は、ユーザーに最も近いノードにリソースをキャッシュすることで、より高速で信頼性の高いコンテンツ配信を提供し、長距離ネットワーク全体の遅延や輻輳を軽減できます。

CDNのメリット

  • CDN はオリジンサーバーの負荷を分散できます。Web サイトに多数のユーザーがアクセスすると、CDN ノードが静的リソースをキャッシュして提供できるため、オリジンサーバーへの負荷が軽減され、Web サイトの安定性とスケーラビリティが向上します。
  • CDN を使用すると、静的リソースの読み込みを高速化できます。一般的に使用される CSS および JavaScript ファイルを CDN でホストします。ユーザーが Web サイトにアクセスすると、最も近い CDN ノードからこれらのファイルを読み込むことができるため、Web ページの読み込みが高速化され、ユーザー エクスペリエンスが向上します。

ファイルを CDN に同期する一般的な方法をいくつか示します。

手動同期

静的リソースを CDN プロバイダーのコンソールにアップロードし、同期操作を手動でトリガーします。この方法は、静的リソースの更新頻度が低い状況に適しています。

自動同期

スクリプトまたはツールを通じて静的リソースを CDN に自動的に同期します。FTP や Rsync などのツールを使用したり、スケジュールされた同期用のスクリプトを作成したりできます。この方法は、静的リソースが頻繁に更新されるシナリオに適しています。1. 同期には rsync ツールを使用します。rsync は、ローカル サーバーとリモート サーバー間でファイルを同期するために使用できる強力なファイル同期ツールです。

基本的な構文は次のとおりです。

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

このうち、SRC はソース ファイルまたはディレクトリのパス、DEST はターゲット ファイルまたはディレクトリのパスです。

一般的に使用される rsync オプションをいくつか示します。

  • -a: アーカイブ モード。アクセス許可、所有者とグループ、タイムスタンプなどを含むファイルのすべての属性を保持します。
  • -v: 詳細な出力を表示します。ファイル同期の進行状況と結果を確認できます。
  • -z: 圧縮された送信を有効にし、ネットワーク送信を高速化します。
  • --delete: ソース ディレクトリに存在しない、ターゲット ディレクトリ内のファイルを削除します。
  • --exclude: 指定したファイルまたはディレクトリを除外します。ワイルドカードを使用できます。

いくつかの使用例を次に示します。

  • ローカル ディレクトリ /path/to/source をリモート サーバーの /path/to/destination ディレクトリに同期します。
ruby复制代码rsync -avz /path/to/source remoteuser@remotehost:/path/to/destination
  • ファイルを同期するときに特定のファイルまたはディレクトリを除外します。
ruby复制代码rsync -avz --exclude 'file.txt' /path/to/source remoteuser@remotehost:/path/to/destination

rsync はローカル サーバーとリモート サーバーの両方にインストールされ、使用できる必要があります。また、rsync を使用する場合は、ソース ファイルと宛先ファイルにアクセスするための十分な権限があることを確認してください。

  1. 同期には scp コマンドを使用します。SCP (Secure Copy) は、ローカル ホストとリモート ホスト間で安全なファイル転送を行うためのコマンド ライン ツールです。SSH プロトコルに基づいており、暗号化されたデータ送信を提供します。

SCP を使用したファイル転送の基本的な構文は次のとおりです。

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

このうち、[オプション]はオプションであり、接続ポートや指定キーなどの一部のパラメータを指定するために使用できます。[ソース ファイル パス] は、転送するファイルまたはディレクトリのパスで、ローカル パスまたはリモート パスを指定できます。[宛先パス] はファイル転送の宛先パスであり、ローカル パスまたはリモート パスを指定できます。

一般的に使用される SCP コマンドの例をいくつか示します。

  • ローカル ホストからリモート ホストにファイルをコピーします。
ruby复制代码scp /path/to/local/file username@remote:/path/to/remote/directory
  • ディレクトリ全体をローカル ホストからリモート ホストにコピーします。
ruby复制代码scp -r /path/to/local/directory username@remote:/path/to/remote/directory

SCP コマンドを実行するとき、パスワードの入力または認証用のキーの入力が求められる場合があります。リモート ホストがデフォルト以外の SSH ポートを使用する場合は、-P オプションを使用してポート番号を指定できます。

バージョン管理システムに基づく同期

静的リソースをバージョン管理システム (Gitlab など) に配置し、フック スクリプトを通じてそれらを CDN に自動的に同期します。コードが送信されるたびに、同期操作が自動的にトリガーされます。この方法は、静的リソースとコードを同期する必要があるチームのコラボレーションと開発に適しています。

ci を使用して Gitlab でファイルを同期します。

  1. GitLab ランナーをインストールする
  2. Runner 登録を実行し、プロンプトに従ってトークンなどの内容を入力します (関連する内容は gitlab Web サイトで参照できます)。
arduino复制代码gitlab-runner register

 

  1. GitLab リポジトリに .gitlab-ci.yml という名前のファイルを作成し、job という名前のタスクを定義します。例えば:
yaml复制代码job:
  script:
    - sh script.sh

ファイルはscript.shで同期できます。

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

4. .gitlab-ci.yml ファイルを GitLab リポジトリに送信してプッシュします。5. コードを送信すると、GitLab は定義されたタスクを自動的に実行し、シェル スクリプトを実行します。

GitLab リポジトリで CI/CD が有効になっていること、および GitLab Runner が適切に構成され、リポジトリに接続されていることを確認する必要があることに注意してください。

API同期

一部の CDN プロバイダーは、API を呼び出すプログラムを作成することで静的リソースを同期するために使用できる API インターフェイスを提供します。API を通じて、より柔軟で洗練されたリソース同期操作を実現できます。たとえば、Alibaba Cloud では、CDN を使用して OSS アクセスを高速化し、oss API を使用してファイルを同期します。

main.ts

javascript复制代码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

typescript复制代码

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 に配置してファイルを同期するなどがあります。各方法には適用可能なシナリオと利点があり、読者は自身のプロジェクトのニーズに応じて適切な方法を選択できます。実際のアプリケーションでは、プロジェクトの規模、訪問回数、リソースの更新頻度などを総合的に考慮して、最適な静的リソース アクセス方法を選択できます。

 

おすすめ

転載: blog.csdn.net/Cipher_Y/article/details/132168579