首页 > 解决方案 > 使用 $.ajax 上传文件和字符串:非法调用或空表单数据

问题描述

在网页上,我需要将图像文件和 ID 字符串都上传到服务器。通常,我使用$.ajax. 正如上传文件时经常发生的那样,$.ajax抛出一个Uncaught TypeError: Illegal invocation因为该函数默认尝试将文件对象转换为字符串。processData设置为false防止这种情况是常见的建议。

但我不能使用这个选项:

我的代码有什么特别之处,我还能做什么?

下面是大部分的 JS 代码。通过在表格行的最后一个单元格中放置图像来触发文件上传。我需要上传存储在同一表格行的(隐藏)第一个单元格中的图像和 ID。

<script>
  // dragover-listener omitted

  // Add listeners for drop event to each cell in last column
  let imageCells = Array.from(document.getElementsByClassName('image'));
  imageCells.forEach(function(cell) {
    cell.addEventListener('drop', fileSelect);
  });

  // Handle drop event
  function fileSelect(event) {
    event.preventDefault();

    // Get data for AJAX request: ID and new image
    let parentRow = event.target.closest('tr');
    let id = parentRow.cells[0].textContent;

    let data = {
      id:    id,
      image: event.dataTransfer.files[0]
    }

    // data is available
    console.log(data);

    let ajaxRequest = $.ajax({
      url:         '/map/set-image',
      type:        'POST',
      processData: false,
      data:        data
    });

    ajaxRequest.done(function(msg) {
      console.log(msg);
    });

    // fail handler omitted
  }
</script>

编辑:一些示例 HTML

<tr>
    <td class="hidden">4</td>
    <td contenteditable="true">John</td>
    <td contenteditable="true">Doe</td>
    <td contenteditable="true">john.doe@example.com</td>
    <td contenteditable="true">555 12345</td>
    <td class="image"><img src="/img/avatars/4.jpg"></td>
</tr>

标签: javascriptjqueryajaxfile-upload

解决方案


只是为了尝试不同的东西,我使用了一个FormData对象(而不是一个普通的对象)来收集我的数据。所以我换了

let data = {
  id:    id,
  image: event.dataTransfer.files[0]
}

let data = new FormData();
data.append('image', event.dataTransfer.files[0]);
data.append('id', id);

还没用,我还是要把第三行换成data.append('id', String(id));

似乎请求失败了,因为当我关闭将请求数据自动转换为字符串 ( processData: false) 时,ID 被视为数字。

请注意,单独的字符串转换并不能解决问题,只是在初始版本中使用String(id)id不是不起作用 - 我仍然想知道为什么。


推荐阅读