我想用jQuery异步上传文件。

$(文档).ready(函数(){$(“#uploadbutton”).click(函数(){var filename=$(“#file”).val();$.ajax美元({类型:“POST”,url:“addFile.do”,enctype:'多部分/表单数据',数据:{文件:文件名},成功:函数(){alert(“上传的数据:”);}});});});<script src=“https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js“></script><span>文件</span><input type=“file”id=“file”name=“file”size=“10”/><input id=“uploadbutton”type=“button”value=“Upload”/>

我只得到文件名,而不是上传文件。我可以做什么来解决这个问题?


当前回答

如果使用承诺使用哪种ajax,并检查文件是否有效并保存在后端,那么您可以在用户浏览页面时在前面使用一些动画。

您甚至可以使用递归方法使其并行上传或堆叠

其他回答

为未来读者整理。

异步文件上载

使用HTML5

如果支持FormData和File API(这两个HTML5功能),则可以使用$.ajax()方法使用jQuery上载文件。

您也可以在不使用FormData的情况下发送文件,但无论哪种方式,文件API都必须以XMLHttpRequest(Ajax)发送的方式处理文件。

$.ajax({
  url: 'file/destination.html', 
  type: 'POST',
  data: new FormData($('#formWithFiles')[0]), // The form with the file inputs.
  processData: false,
  contentType: false                    // Using FormData, no need to process data.
}).done(function(){
  console.log("Success: Files sent!");
}).fail(function(){
  console.log("An error occurred, the files couldn't be sent!");
});

有关快速纯JavaScript(无jQuery)示例,请参阅“使用FormData对象发送文件”。

退路

当HTML5不受支持(没有文件API)时,唯一的其他纯JavaScript解决方案(没有Flash或任何其他浏览器插件)是隐藏的iframe技术,它允许在不使用XMLHttpRequest对象的情况下模拟异步请求。

它包括使用文件输入将iframe设置为表单的目标。当用户提交请求并上传文件时,响应显示在iframe中,而不是重新呈现主页。隐藏iframe使整个过程对用户透明,并模拟异步请求。

如果处理得当,它实际上应该可以在任何浏览器上运行,但它对如何从iframe中获取响应有一些警告。

在这种情况下,您可能更喜欢使用像Bifröst这样的包装器插件,它使用iframe技术,但也提供jQueryAjax传输,允许仅使用$.Ajax()方法发送文件,如下所示:

$.ajax({
  url: 'file/destination.html', 
  type: 'POST',
  // Set the transport to use (iframe means to use Bifröst)
  // and the expected data type (json in this case).
  dataType: 'iframe json',                                
  fileInputs: $('input[type="file"]'),  // The file inputs containing the files to send.
  data: { msg: 'Some extra data you might need.'}
}).done(function(){
  console.log("Success: Files sent!");
}).fail(function(){
  console.log("An error occurred, the files couldn't be sent!");
});

插件

Bifröst只是一个小包装,它为jQuery的ajax方法添加了回退支持,但前面提到的许多插件,如jQuery表单插件或jQuery文件上载,都包括从HTML5到不同回退的整个堆栈,以及一些有用的功能来简化过程。根据您的需要和要求,您可能需要考虑一个简单的实现或其中一个插件。

注意:此答案已过时,现在可以使用XHR上载文件。


不能使用XMLHttpRequest(Ajax)上载文件。可以使用iframe或Flash模拟效果。优秀的jQuery表单插件,通过iframe发布文件以获得效果。

在使用XMLHttpRequest进行异步上载时,可以传递附加参数和文件名(不依赖flash和iframe)。将附加参数值附加到FormData并发送上载请求。


var formData = new FormData();
formData.append('parameter1', 'value1');
formData.append('parameter2', 'value2'); 
formData.append('file', $('input[type=file]')[0].files[0]);

$.ajax({
    url: 'post back url',
    data: formData,
// other attributes of AJAX
});

此外,Syncfusion JavaScript UI文件上传只需使用事件参数即可为该场景提供解决方案。您可以在此处找到文档,并在此处输入链接描述

使用|HTML5的readAsDataURL()或一些base64编码器将文件转换为base64。在这里摆弄

var reader = new FileReader();

        reader.onload = function(readerEvt) {
            var binaryString = readerEvt.target.result;
            document.getElementById("base64textarea").value = btoa(binaryString);
        };

        reader.readAsBinaryString(file);

然后检索:

window.open("data:application/octet-stream;base64," + base64);

在此处查找“异步处理文件的上载过程”:https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications

链接中的示例

<?php
if (isset($_FILES['myFile'])) {
    // Example:
    move_uploaded_file($_FILES['myFile']['tmp_name'], "uploads/" . $_FILES['myFile']['name']);
    exit;
}
?><!DOCTYPE html>
<html>
<head>
    <title>dnd binary upload</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <script type="text/javascript">
        function sendFile(file) {
            var uri = "/index.php";
            var xhr = new XMLHttpRequest();
            var fd = new FormData();

            xhr.open("POST", uri, true);
            xhr.onreadystatechange = function() {
                if (xhr.readyState == 4 && xhr.status == 200) {
                    // Handle response.
                    alert(xhr.responseText); // handle response.
                }
            };
            fd.append('myFile', file);
            // Initiate a multipart/form-data upload
            xhr.send(fd);
        }

        window.onload = function() {
            var dropzone = document.getElementById("dropzone");
            dropzone.ondragover = dropzone.ondragenter = function(event) {
                event.stopPropagation();
                event.preventDefault();
            }

            dropzone.ondrop = function(event) {
                event.stopPropagation();
                event.preventDefault();

                var filesArray = event.dataTransfer.files;
                for (var i=0; i<filesArray.length; i++) {
                    sendFile(filesArray[i]);
                }
            }
        }
    </script>
</head>
<body>
    <div>
        <div id="dropzone" style="margin:30px; width:500px; height:300px; border:1px dotted grey;">Drag & drop your file here...</div>
    </div>
</body>
</html>