在 post 请求中发送文件

Chr*_*ler 6 javascript ajax jquery

在 python 中,我发送这样的文件:

with open('D:\\someimage.jpg', 'rb') as image:
imager = image.read()
files = {'image': imager}
r = requests.post(url, files=files)
Run Code Online (Sandbox Code Playgroud)

我想在 js 中做类似的事情,但我总是收到 400 Bad Request 错误。我认为问题是我不知道文件应该具有什么类型。我尝试过以初始“文件”类型传递它,作为数组缓冲区,作为二进制字符串 - 没有任何效果。这是我的代码:

var reader = new FileReader();
reader.readAsArrayBuffer(aFiles[0]);
reader.onload = function () {
var arrayBuffer = this.result,
array = new Uint8Array(arrayBuffer),
binaryString = String.fromCharCode.apply(null, array);
jQuery.ajax({
    url: '/streamer', 
    method: 'POST',
    files: {'image': binaryString},
    success: function(response) {
        alert(response);
    },
    error: function(xhr, status, error) {
       alert(JSON.parse(xhr.responseText));
    }});
Run Code Online (Sandbox Code Playgroud)

End*_*ess 7

如果您需要发送更多字段,则可以将文件作为 FormData (multipart/form-data) 发送;如果您只想直接发送二进制文件,则可以将文件作为 Blob 发送。

jQuery 尝试智能地处理您发送的数据。但 jQuery 不理解 FormData 或 blob,它将其视为对象并做了错误的事情。这就是为什么您需要设置processData = false并且不要通过执行来设置错误的请求内容类型contentType = false,而只是让 xhr 自己执行此操作。

var fd = new FormData();
fd.append('image', aFiles[0] /*, optional filename */)

var req = jQuery.ajax({
  url: '/streamer', 
  method: 'POST',
  data: fd, // sends fields with filename mimetype etc
  // data: aFiles[0], // optional just sends the binary
  processData: false, // don't let jquery process the data
  contentType: false // let xhr set the content type
});

// jQuery is promise A++ compatible and is the todays norms of doing things 
req.then(function(response) {
  console.log(response)
}, function(xhr) {
  console.error('failed to fetch xhr', xhr)
})
Run Code Online (Sandbox Code Playgroud)

但是,如果您只支持具有fetch api 的最新浏览器,那么您实际上并不需要 jQuery。

var req = fetch('/streamer', {
  method: 'post',
  body: fd /* or aFile[0]*/
}); // returns a promise

req.then(function(response) {
  // returns status + response headers
  // but not yet the body, 
  // for that call `response[text() || json() || arrayBuffer()]` <-- also promise

  if (res.ok) {
    // status code was 200-299
  } else {
    // status was something else
  }
}, function(error) {
  console.error('failed due to network error or cross domain')
})
Run Code Online (Sandbox Code Playgroud)