You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js中导入image-compressor.js报错window未定义及后续问题求助

解决Next.js中使用image-compressor.js的window未定义及状态变量问题

核心原因

image-compressor.js依赖浏览器环境的window对象,而Next.js默认的服务端渲染(SSR)阶段不存在window,直接全局导入会触发Uncaught ReferenceError: window is not defined错误。你第二次尝试的动态导入写法存在导出匹配错误,导致压缩逻辑执行异常,进而影响状态变量设置。

正确实现步骤

1. 修正动态导入方式

image-compressor.js是默认导出,需调整动态导入的语法,同时添加{ ssr: false }确保库仅在浏览器端加载:

const compressImage = async (file) => {
  try {
    // 仅在浏览器端导入,禁用SSR,匹配默认导出
    const { default: ImageCompressor } = await import("image-compressor.js", { ssr: false });

    return new Promise((resolve, reject) => {
      new ImageCompressor(file, {
        quality: 0.5,
        success(result) {
          const reader = new FileReader();
          reader.onload = (e) => {
            // 直接使用readAsDataURL的base64结果,无需手动编码
            resolve(e.target.result);
          };
          // 改用readAsDataURL避免二进制字符串编码问题
          reader.readAsDataURL(result);
        },
        error(e) {
          reject(e);
        },
      });
    });
  } catch (error) {
    console.error("Error importing ImageCompressor:", error);
    throw error; // 抛出错误让上层handleImage逻辑处理
  }
};

2. 确保压缩逻辑仅在浏览器执行

在触发压缩的函数中,先判断当前环境为浏览器,避免服务端渲染时执行:

const handleImage = async (e) => {
  if (typeof window === 'undefined') return;
  
  const selectedFile = e.target.files[0];
  if (selectedFile) {
    try {
      const compressedDataURL = await compressImage(selectedFile);
      console.log("Compressed dataURL: ", compressedDataURL);
      setImage(compressedDataURL);
    } catch (error) {
      console.error("Error compressing image:", error);
    }
  }
};

3. 备选方案:服务端压缩

如果客户端压缩仍有兼容性问题,可改为将图片上传至后端,使用Sharp等库在服务端完成压缩,再返回压缩后的图片URL给前端,这种方式更稳定且无需依赖浏览器环境。


内容的提问来源于stack exchange,提问作者Shazib Mahmood

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 13:05:11