一、为什么需要MD5校验和
在前端开发过程中,我们经常需要加载网络上的静态资源,例如 JavaScript 文件、CSS 文件、图片等。如果文件在网络传输的过程中被修改或篡改,或者服务器上文件被修改,那么将会导致页面的异常。为了避免这种情况,需要使用 MD5 校验和来保证文件的完整性。
MD5 是一种哈希算法,将任意长度的信息压缩成一个128位(16字节)的信息摘要,具有不可逆、唯一性、不冲突的特点,能够有效地保护数据的完整性。
二、如何在 TypeScript/JavaScript 项目中引入 MD5 校验和
- 使用 Node.js 中的 crypto 模块
Node.js 中自带了一个 crypto 模块,支持多种哈希算法,包括 MD5。
示例1:计算字符串的 MD5 校验和
import crypto from 'crypto';
function calculateMD5(str: string): string {
const hash = crypto.createHash('md5');
hash.update(str);
return hash.digest('hex');
}
const md5 = calculateMD5('hello world'); // '5eb63bbbe01eeed093cb22bb8f5acdc3'
示例2:计算文件的 MD5 校验和
import fs from 'fs';
import crypto from 'crypto';
function calculateFileMD5(path: string): Promise<string> {
return new Promise((resolve, reject) => {
const hash = crypto.createHash('md5');
const stream = fs.createReadStream(path);
stream.on('error', reject);
stream.on('data', data => hash.update(data));
stream.on('end', () => resolve(hash.digest('hex')));
});
}
async function main() {
const fileMD5 = await calculateFileMD5('file.txt');
console.log(fileMD5); // '3f3fc34bb032dc642beb6cda2dbc3f6c'
}
main();
- 使用第三方库 md5.js
md5.js 是纯 JavaScript 编写的 MD5 实现,可以在浏览器和 Node.js 环境下使用。
示例3:计算字符串的 MD5 校验和
import md5 from 'md5';
const strMD5 = md5('hello world'); // '5eb63bbbe01eeed093cb22bb8f5acdc3'
示例4:计算文件的 MD5 校验和
import fs from 'fs';
import md5 from 'md5';
function calculateFileMD5(path: string): Promise<string> {
return new Promise((resolve, reject) => {
const stream = fs.createReadStream(path);
let md5sum = md5('');
stream.on('error', reject);
stream.on('data', data => md5sum = md5(md5sum + data));
stream.on('end', () => resolve(md5sum));
});
}
async function main() {
const fileMD5 = await calculateFileMD5('file.txt');
console.log(fileMD5); // '3f3fc34bb032dc642beb6cda2dbc3f6c'
}
main();
三、在项目中引入 MD5 校验和
通过使用前面介绍的方法,我们可以计算出每个静态资源文件的 MD5 校验和。为了避免缓存问题,我们可以将计算出的 MD5 校验和作为静态资源文件的版本号,每次文件内容发生变化时更新版本号,这样浏览器就会重新下载文件,而不会从缓存中读取旧文件。
示例5:使用 webpack 打包项目,并自动添加 MD5 校验和版本号
const path = require('path');
const md5 = require('md5');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.ts',
output: {
filename: '[name].[contenthash].js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[contenthash].[ext]'
}
}
]
}
]
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: 'index.html',
favicon: 'favicon.ico'
})
],
resolve: {
extensions: ['.tsx', '.ts', '.js']
},
optimization: {
moduleIds: 'hashed',
runtimeChunk: 'single',
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
},
output: {
filename: '[name].[contenthash].js',
path: path.resolve(__dirname, 'dist')
},
devServer: {
contentBase: './dist'
},
};
function addVersionParam(url) {
const version = md5(url).slice(0, 8);
return `${url}?v=${version}`;
}
// 修正 webpack 的输出文件路径,添加 MD5 校验和版本号
const originalPublicPath = __webpack_public_path__;
__webpack_public_path__ = function(url, ...args) {
if (url.endsWith('.css') || url.endsWith('.js') || url.endsWith('.png') || url.endsWith('.svg') || url.endsWith('.jpg') || url.endsWith('.gif')) {
url = addVersionParam(url);
}
return originalPublicPath.call(this, url, ...args);
};
在 webpack 配置文件中添加以上代码后,当打包完成后,输出的文件名中就会自动包含 MD5 校验和版本号,例如 main.3f3fc34b.js。
在 HTML 文件中引入这些文件时,也需要将文件名添加版本号,代码如下:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My App</title>
<link rel="stylesheet" href="<%= require('./main.css') %>" />
</head>
<body>
<script src="<%= require('./main.js') %>"></script>
</body>
</html>
注意:由于以上代码使用了 md5()
方法,所以需要先在项目中安装 md5.js 库,例如:npm install md5
。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:TypeScript与JavaScript项目里引入MD5校验和 - Python技术站