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

如何结合AJAX Post使用browser-image-compression脚本实现图片压缩上传

图片压缩后AJAX上传失败问题解决

我是Javascript新手,想通过AJAX上传图片到服务器,但图片体积太大需要先压缩。找到browser-image-compression脚本后,折腾了5小时还是没成功——AJAX仍然传输原尺寸图片,控制台还报Uncaught (in promise) ReferenceError: compressedFile is not defined错误。

核心错误原因

  1. 异步执行顺序错误:imageCompression是异步Promise操作,你的AJAX代码在它外部同步执行,此时压缩还没完成,compressedFile根本不存在,所以报错。
  2. 变量作用域问题:compressedFile只在then回调函数内部有定义,外部代码无法访问这个变量。
  3. 语法错误:代码里.then(function (compressedFile) {+多了一个多余的+号,会破坏代码结构。

修复方案

关键修复步骤

  1. 将AJAX上传代码完全移到imageCompression的then回调内部,确保只有拿到压缩后的文件才执行上传。
  2. 移除回调函数开头多余的+号。
  3. 可选:用async/await改写代码,让异步逻辑更直观(适合新手理解)。

修正后的核心代码片段

// 替换原来的imageCompression及后续AJAX代码部分
const options = {
  maxWidthOrHeight: 1000,
  useWebWorker: true
}

imageCompression(original_file, options)
.then(function (compressedFile) {
    console.log('compressedFile instanceof Blob', compressedFile instanceof Blob); // true
    console.log(`compressedFile size ${compressedFile.size / 1024 / 1024} MB`);
    
    // 在这里创建FormData并执行AJAX上传
    var filedata = new FormData();
    filedata.append('game', game);
    filedata.append('data', image_type);
    filedata.append('input_val', "image");
    filedata.append('file', compressedFile);

    $.ajax({
      url: 'editimage.php',
      type: 'POST',
      data: filedata,
      dataType: "json",
      cache:false,
      contentType: false,
      processData: false,
      beforeSend: function() {
          var percentVal = '0%';
          var percentVal2 = '0';
          progress_bar.attr("aria-valuenow", percentVal2);
          progress_bar.css("width", percentVal);
          progress_percent.text(percentVal);
      },
      uploadProgress: function(event, position, total, percentComplete) {
          var percentVal = percentComplete + '%';
          progress_bar.attr("aria-valuenow", percentComplete);
          progress_bar.css("width", percentVal);
          progress_percent.text(percentVal);
      },
      complete: function(xhr) {
        var percentVal = '100%';
        var percentVal2 = '100';
          progress_bar.attr("aria-valuenow", percentVal2);
          progress_bar.css("width", percentVal);
          progress_percent.text(percentVal);
      },
      success: function(result){
        if (result.status == true) {
          // 添加成功后的业务逻辑
        }
        else {
          // 添加失败后的业务逻辑
        }                 
      },
      error: function(xhr, status, error) {
        console.error('上传失败:', error);
      }
    });
})
.catch(function (error) {
    console.error('压缩失败:', error.message);
});

用async/await改写的版本(更易读)

如果你的环境支持ES6+,可以用async/await让代码逻辑更线性:

// 将then回调部分改成async函数形式
if(result.value){
  var file_input = $('#gp-imageupload-fileElem');
  var progress_bar = $('#gp-imageupload-progressbar');
  var progress_percent = $('#gp-imageupload-progressbar-span');
  var original_file = $('#gp-imageupload-fileElem')[0].files[0];
  const options = {
    maxWidthOrHeight: 1000,
    useWebWorker: true
  };

  try {
    // 等待压缩完成
    const compressedFile = await imageCompression(original_file, options);
    console.log('compressedFile instanceof Blob', compressedFile instanceof Blob);
    console.log(`compressedFile size ${compressedFile.size / 1024 / 1024} MB`);
    
    // 构建表单数据
    var filedata = new FormData();
    filedata.append('game', game);
    filedata.append('data', image_type);
    filedata.append('input_val', "image");
    filedata.append('file', compressedFile);

    // 执行AJAX上传
    $.ajax({
      url: 'editimage.php',
      type: 'POST',
      data: filedata,
      dataType: "json",
      cache:false,
      contentType: false,
      processData: false,
      beforeSend: function() {
          var percentVal = '0%';
          var percentVal2 = '0';
          progress_bar.attr("aria-valuenow", percentVal2);
          progress_bar.css("width", percentVal);
          progress_percent.text(percentVal);
      },
      uploadProgress: function(event, position, total, percentComplete) {
          var percentVal = percentComplete + '%';
          progress_bar.attr("aria-valuenow", percentComplete);
          progress_bar.css("width", percentVal);
          progress_percent.text(percentVal);
      },
      complete: function(xhr) {
        var percentVal = '100%';
        var percentVal2 = '100';
          progress_bar.attr("aria-valuenow", percentVal2);
          progress_bar.css("width", percentVal);
          progress_percent.text(percentVal);
      },
      success: function(result){
        if (result.status == true) {
          // 添加成功后的业务逻辑
        }
        else {
          // 添加失败后的业务逻辑
        }                 
      },
      error: function(xhr, status, error) {
        console.error('上传失败:', error);
      }
    });
  } catch (error) {
    console.error('处理失败:', error.message);
  }
}

内容的提问来源于stack exchange,提问作者David T Türkiye

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 18:48:24