前端页面用户选择静态资源布置的图片,想拿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 编码,可能会增加页面的加载时间和资源消耗。