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

不修改编码读取ISO-8859-1编码CSV文件的JS实现问题

问题描述

我有一个CSV文件,通过命令file -bi myCsv.txt查询得知其字符集为iso-8859-1。现在想通过JavaScript从type="file"的input标签读取该文件,且不修改其编码,但尝试了以下方法后,通过Ajax POST发送到后端时编码都变成了UTF-8:

  • FileReader()的readAsText()、readAsArrayBuffer()方法
  • 结合fetch API和new Uint8Array(arrayBuffer)的方式

原本以为仅读取文件字节不会修改编码,但实际FileReader()和fetch API的处理导致编码改变,请问如何读取文本文件且保留原编码,让后端能正常检测?

以下是我尝试以byte[]形式发送文件的代码:

async function sendFileToValidation() {
      const file = document.getElementById("uploadFile").files[0];
      try {
        const fileURL = URL.createObjectURL(file);              
        const response = await fetch(fileURL); //不确定这里用的是什么编码
        const arrayBuffer = await response.arrayBuffer();
        const byteArray = new Uint8Array(arrayBuffer);       
        $.ajax({
          url: '/validateOnBackend',
          type: 'POST',
          contentType: 'application/octet-stream',
          data: byteArray,
          success: function (response) {
            alert("we can process this encoding!!!!" + response);
          },
          error: function (xhr, status, error) {
            alert("Error: " + xhr.responseText);
          }
        });

        return byteArray;
      } catch (error) {
        console.error('error', error);
      }

    }
解决方案

核心问题是:jQuery的$.ajax在处理Uint8Array时,会自动将其转换为UTF-8编码的字符串,破坏了原字节流。要保留原文件的字节编码,需要直接发送原始的文件二进制数据,避免中间的编码转换。

方法1:直接发送File对象(最简洁)

不需要读取或转换,直接把File对象通过FormData发送,后端可以直接获取原始字节流:

async function sendFileToValidation() {
  const file = document.getElementById("uploadFile").files[0];
  if (!file) return;

  const formData = new FormData();
  formData.append('uploadedFile', file); // 后端可通过这个字段获取文件

  $.ajax({
    url: '/validateOnBackend',
    type: 'POST',
    data: formData,
    contentType: false, // 必须设为false,让浏览器自动设置正确的Content-Type(包含boundary)
    processData: false, // 禁止jQuery处理数据,避免编码转换
    success: function(response) {
      alert("编码可正常处理!" + response);
    },
    error: function(xhr, status, error) {
      alert("错误:" + xhr.responseText);
    }
  });
}

方法2:用XMLHttpRequest发送ArrayBuffer(绕过jQuery的自动处理)

如果不需要FormData,直接发送原始字节流,用原生XHR更可靠:

async function sendFileToValidation() {
  const file = document.getElementById("uploadFile").files[0];
  if (!file) return;

  try {
    const arrayBuffer = await new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onload = () => resolve(reader.result);
      reader.onerror = reject;
      reader.readAsArrayBuffer(file); // 直接读取原始字节,不做编码转换
    });

    const xhr = new XMLHttpRequest();
    xhr.open('POST', '/validateOnBackend');
    xhr.setRequestHeader('Content-Type', 'application/octet-stream');
    xhr.onload = function() {
      if (xhr.status === 200) {
        alert("编码可正常处理!" + xhr.responseText);
      } else {
        alert("错误:" + xhr.responseText);
      }
    };
    xhr.onerror = function() {
      alert("请求错误");
    };
    xhr.send(arrayBuffer); // 发送原始ArrayBuffer,保留原字节
  } catch (error) {
    console.error('读取文件失败:', error);
  }
}

方法3:修复原fetch+jQuery的方案

如果坚持用fetch和jQuery,需要把ArrayBuffer转成Blob再发送,避免jQuery处理Uint8Array时的编码转换:

async function sendFileToValidation() {
  const file = document.getElementById("uploadFile").files[0];
  if (!file) return;

  try {
    const arrayBuffer = await file.arrayBuffer(); // 直接用File的arrayBuffer方法,更简洁
    const blob = new Blob([arrayBuffer], { type: 'application/octet-stream' });

    $.ajax({
      url: '/validateOnBackend',
      type: 'POST',
      data: blob,
      contentType: 'application/octet-stream',
      processData: false, // 关键:禁止jQuery处理Blob,避免编码转换
      success: function(response) {
        alert("编码可正常处理!" + response);
      },
      error: function(xhr, status, error) {
        alert("错误:" + xhr.responseText);
      }
    });
  } catch (error) {
    console.error('错误:', error);
  }
}

关键注意点

  • 无论用哪种方法,都要确保不对文件内容做字符串解码/编码操作(比如readAsText会把字节转成字符串,默认用UTF-8,会破坏原编码)。
  • jQuery的$.ajax默认会处理数据,设置processData: false可以避免它把二进制数据转成UTF-8字符串。
  • 直接发送File/Blob/ArrayBuffer都是保留原始字节流的方式,后端接收到的就是原文件的ISO-8859-1编码字节,可以正常检测。

内容的提问来源于stack exchange,提问作者Roma Kap

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 03:11:18