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

Angular5/TypeScript项目IE9下无Ajax/jQuery的FormData兼容方案

嘿,这个IE9的FormData问题确实挺头疼的,毕竟它是个老古董了,而且你不想用jQuery和Ajax,那我给你两个靠谱的纯原生解决方案:

方案一:添加FormData Polyfill(贴近现代代码逻辑)

IE9原生压根没有FormData构造函数,我们可以自己加一个轻量的纯JS polyfill,完全不依赖第三方库。

步骤1:引入Polyfill

把这段代码添加到你的项目polyfills.ts文件里(或者在组件加载前执行):

if (typeof FormData === 'undefined') {
  window.FormData = function() {
    const formData = {};
    const boundary = '----FormDataPolyfill' + Math.random();
    
    this.append = function(key, value, filename) {
      formData[key] = {
        value: value,
        filename: filename || key
      };
    };
    
    this.toString = function() {
      const parts = [];
      for (const key in formData) {
        if (formData.hasOwnProperty(key)) {
          const item = formData[key];
          parts.push('--' + boundary);
          if (item.value instanceof File) {
            // IE9的File对象支持getAsBinary方法获取文件内容
            parts.push('Content-Disposition: form-data; name="' + key + '"; filename="' + item.filename + '"');
            parts.push('Content-Type: ' + (item.value.type || 'application/octet-stream'));
            parts.push('');
            parts.push(item.value.getAsBinary());
          } else {
            parts.push('Content-Disposition: form-data; name="' + key + '"');
            parts.push('');
            parts.push(item.value);
          }
        }
      }
      parts.push('--' + boundary + '--');
      parts.push('');
      return parts.join('\r\n');
    };
    
    this.getBoundary = function() {
      return boundary;
    };
  };
}

步骤2:调整请求发送逻辑

因为IE9的XMLHttpRequest不能直接发送原生FormData(我们的polyfill是自定义的),所以要手动设置请求头并处理发送内容:

// 假设这是你的上传请求逻辑
sendUploadRequest() {
  const xhr = new XMLHttpRequest();
  xhr.open('POST', '/你的上传接口地址', true);
  
  // 判断是否用的是我们的polyfill,手动设置Content-Type
  if (typeof (this.formCvData as any).getBoundary === 'function') {
    xhr.setRequestHeader(
      'Content-Type', 
      'multipart/form-data; boundary=' + (this.formCvData as any).getBoundary()
    );
  }
  
  xhr.onreadystatechange = () => {
    if (xhr.readyState === 4) {
      if (xhr.status === 200) {
        // 处理上传成功的逻辑
        console.log('上传成功');
      } else {
        // 处理上传失败的逻辑
        console.error('上传失败');
      }
    }
  };
  
  // 发送请求,polyfill的情况发送toString后的内容,否则正常发送FormData
  xhr.send(
    typeof (this.formCvData as any).getBoundary === 'function' 
      ? (this.formCvData as any).toString() 
      : this.formCvData
  );
}
方案二:用隐藏iframe模拟异步上传(原生兼容IE9)

如果不想折腾polyfill,这个方案更贴合IE9的原生能力,利用表单提交到隐藏iframe来实现无刷新上传:

步骤1:修改组件模板

给表单添加target属性指向隐藏的iframe,同时新增这个隐藏iframe:

<form 
  #formUpload 
  id="formUpload" 
  target="uploadFrame" 
  method="POST" 
  enctype="multipart/form-data"
  action="/你的上传接口地址"
>
  <input type="file" class="input-file-ghost" (change)="onChangeFile($event.target.files)">
  <!-- 隐藏的iframe,用来接收表单提交结果 -->
  <iframe name="uploadFrame" style="display: none;" (load)="onIframeLoad($event)"></iframe>
</form>

步骤2:调整组件TS逻辑

去掉FormData相关代码,直接提交表单,并监听iframe的加载事件获取上传结果:

export class UploadFileComponent implements OnInit { 
  @Input() uploadFileConfig: any; 
  @Output() filesAdded = new EventEmitter<any>(); 
  @ViewChild('formUpload') formUpload: ElementRef; 

  constructor() { } 

  ngOnInit() { } 

  onChangeFile(files: File[]) {
    // 直接提交表单,结果会在隐藏iframe里返回
    this.formUpload.nativeElement.submit();
  }

  onIframeLoad(event: Event) {
    const iframe = event.target as HTMLIFrameElement;
    const response = iframe.contentDocument?.body?.textContent;
    
    try {
      // 解析服务器返回的JSON响应(如果服务器返回的是JSON)
      const result = JSON.parse(response || '{}');
      // 通过事件通知父组件上传结果
      this.filesAdded.emit(result);
    } catch (e) {
      console.error('解析响应失败:', e);
    }

    // 重置表单,支持再次上传
    this.formUpload.nativeElement.reset();
  }
}

注意事项

  • 确保你的Angular5项目已经配置了IE9所需的基础polyfills(比如core-js/es6相关内容),不然Angular本身的代码在IE9里跑不起来。
  • 服务器端要支持传统表单上传的方式接收文件(和接收FormData的逻辑基本一致,大部分后端框架都兼容)。

内容的提问来源于stack exchange,提问作者LYES - CHIOUKH

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:44:09