前端页面用户选择静态资源布置的图片,想拿url却拿到base64编码?
问题的原因;
简单一句话,图片太小了,低于webpack的limit设置的大小,就会自动转换为BASE64,内嵌到页面上,超过limit的才会单独打包为文件的.
如果确保代码中没有对图片进行转换为 Base64 编码的操作,而图片仍然以 Base64 编码的形式加载,那么很可能是在 webpack 的配置中使用了 url-loader 或 file-loader 对图片进行处理。这两个 loader 在对图片进行处理时,会将小于配置文件中指定大小的图片自动转换为 Base64 编码的形式内嵌到 HTML 或 CSS 文件中,大于配置文件中指定大小的图片则会被打包为单独的文件。
最直接的方法就是修改webpack,当然最简单的方法也可以处理图片大小,让他超过limit即可。
因此,可以检查一下webpack 配置文件中的 url-loader 或 file-loader 的配置项,将图片加载方式从 Base64 编码改为通过 URL 加载。其中,主要涉及到以下配置项:
- limit:指定小于该大小的图片会被转换为 Base64 编码的形式。将该值设置为 Infinity 可以避免图片被转换为 Base64 编码。
- fallback:指定生成的文件的 URL 路径。设为
file-loader
,则会将图片打包为单独的文件,并生成相应的 URL 路径。
例如,以下是一份简化的 webpack 配置文件,用来将所有图片打包为单独的文件:
module.exports = {
// ...
module: {
rules: [{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
use: [{
loader: 'file-loader',
options: {
name: 'img/[name].[hash:8].[ext]'
}
}]
}]
}
};
可以将 file-loader
替换为其他相关的 loader,例如 url-loader
。
然后在 Vue CLI 工程中,还需要将 vue.config.js
文件中的相应规则修改为以下内容:
最后,需要根据需求调整生成的 URL 路径
module.exports = {
chainWebpack: config => {
// 移除svg相关loader
config.module.rule('svg')
.uses.clear();
// 添加file-loader处理svg
config.module.rule('svg')
.test(/\.svg$/)
.use('file-loader')
.loader('file-loader')
.options({
name: 'img/[name].[hash:8].[ext]'
})
.end();
}
}
======================================================================
如果只有部分图片被转成了 Base64 编码,也有可能是因为这些图片的加载时机不同。
不过大多数情况是因为图片太小了。
在代码中,只有当用户点击相应的上传按钮并成功选择了一个文件后,才会触发 handleThumbnailChange
方法,并将文件转换为 Base64 编码。
因此,如果某些图片没有被用户选择和上传,那么在页面加载时就会直接以图片路径的形式被渲染到 HTML 中,而不会被转换为 Base64 编码。这就解释了为什么只有部分图片被转换为 Base64 编码。
如果希望所有图片都能被转换为 Base64 编码,可以考虑在组件渲染时,预先将所有图片的路径转换为对应的 Base64 编码。可以使用以下代码的方法:
const fs = require('fs');
const path = require('path');
const imagePath = path.join(__dirname, 'path/to/image.jpg');
const imageBuffer = fs.readFileSync(imagePath);
const base64String = imageBuffer.toString('base64');
// 然后将 base64String 赋值给 img 标签的 src 属性即可
需要注意的是,这种方法会在页面渲染前就将所有图片都从文件转换为 Base64 编码,可能会增加页面的加载时间和资源消耗。