0

我正在尝试使用 javascript 上传多张图片。我能够很好地上传一张图片 - 但是当我上传 n 张图片时,它只会上传该组的第一张图片 n 次。代码如下:

var field = document.getElementById('file-field')

field.addEventListener('change', function(data) {
  var files  = data.target.files

  for(var i=0; i<files.length; i++) {
    multipartPost('/photos/create', files[i]) // I've tried moving this out into another function, an IIFY, etc
  }
})

function multipartPost(url, params, callback) {
  var xml  = new XMLHttpRequest()
  var data = new FormData()
  data.append('file', params, false) // This is where I fixed it so it can at least upload synchronously by passing false as a third param

  xml.open('post', url)
  xml.send(data)

  xml.onreadystatechange = function() {
    if(xml.readyState===4) {
      if(xml.status===200) {
        console.log('success')
      } else {
        console.log(xml.status, "Error")
      }
    }
  }
}

关于如何让它上传所有图片或为什么它重复上传单张图片 n 次的任何想法?


多一点背景:

我最初有一个表单,我将提交它来上传文件,但后来我决定让它通过 javascript 上传。事实证明,使用 XHR2 真的很简单,而且我能够成功上传没有表单的文件 - html 很简单

<input type="file" name="file" id="file-field" multiple />

但是,我决定进行下一步并允许多次上传。我认为这就像在 for 循环中将 files[0] 更改为 files[i] 一样简单,但是如果我上传多个文件,它只需要第一个文件并上传 n 次,n 是文件的数量在文件字段中。


更新

通过将第三个值为 false 的参数传递给函数 XMLHttpRequest.open,我能够使用同步发布请求获取多个文件上传,因此肯定存在与异步相关的错误。我会继续调试,但如果有人知道为什么它不能异步工作,我很好奇


解决方案

var field = document.getElementById('file-field')

field.addEventListener('change', function(e) {
  var files  = e.target.files
  for(var i = 0; i < files.length; i++) {
    multipartPost('/photos/create', files[i], appendPhoto)
  }
})

function appendPhoto(data) {
  // Callback function
}

function multipartPost(url, params, callback) {
  var xml  = new XMLHttpRequest()
  var data = new FormData() // Using FormData allows me to keep my server-side code the same, just as if it were a form submission
  data.append('file', params)

  xml.open('post', url) // No third param will default to async: true
  xml.setRequestHeader("X-Requested-With","XMLHttpRequest") // This header allows me to recognize the request as xhr server side
  xml.send(data)

  xml.onreadystatechange = function() {
    if(xml.readyState===4) {
      if(xml.status===200) {
        callback(xml.responseText)
      } else {
        console.log(xml.status, "Error")
      }
    }
  }
}
4

2 回答 2

0

代码似乎不正确。也许在发布时手动编辑后:查看 for 循环。在循环内使用“index”变量时声明并使用了“i”变量。我也看到没有给出回调参数。我不确定这里的任何内容都与关闭有关。你打算在这段代码的帮助下做什么?

于 2013-10-23T22:23:35.443 回答
0

实际上有一个异步错误保存到数据库服务器端 - 上面的代码有效。但是,在打开请求后,如果您希望能够将其识别为 xhr,则必须设置标头。您必须设置的标题如下,但我将代码更新为我在上面的问题中使用的最终代码:

xml.setRequestHeader("X-Requested-With","XMLHttpRequest")
于 2013-10-26T17:27:04.200 回答