jQuery 如何使用 JSP/Servlet 和 Ajax 将文件上传到服务器?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6914152/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to upload files to server using JSP/Servlet and Ajax?
提问by Nachshon Schwartz
I'm creating a JSP/Servlet web application and I'd like to upload a file to a Servlet via Ajax. How would I go about doing this? I'm using jQuery.
我正在创建一个 JSP/Servlet Web 应用程序,我想通过 Ajax 将文件上传到 Servlet。我该怎么做呢?我正在使用 jQuery。
I've done so far:
到目前为止我已经完成了:
<form class="upload-box">
<input type="file" id="file" name="file1" />
<span id="upload-error" class="error" />
<input type="submit" id="upload-button" value="upload" />
</form>
With this jQuery:
使用这个 jQuery:
$(document).on("#upload-button", "click", function() {
$.ajax({
type: "POST",
url: "/Upload",
async: true,
data: $(".upload-box").serialize(),
contentType: "multipart/form-data",
processData: false,
success: function(msg) {
alert("File has been uploaded successfully");
},
error:function(msg) {
$("#upload-error").html("Couldn't upload file");
}
});
});
However, it doesn't appear to send the file contents.
但是,它似乎没有发送文件内容。
回答by BalusC
To the point, as of the current XMLHttpRequest
version 1 as used by jQuery, it is notpossible to upload files using JavaScript through XMLHttpRequest
. The common workaround is to let JavaScript create a hidden <iframe>
and submit the form to it instead so that the impression is created that it happens asynchronously. That's also exactly what the majority of the jQuery file upload plugins are doing such as jQuery Form plugin(example here).
为了这一点,因为目前XMLHttpRequest
所使用的jQuery版本1,它是不是可以通过上传使用JavaScript文件XMLHttpRequest
。常见的解决方法是让 JavaScript 创建一个隐藏的<iframe>
并将表单提交给它,以便创建它异步发生的印象。这也正是大多数 jQuery 文件上传插件正在做的事情,例如jQuery Form 插件(示例在这里)。
Assuming that your JSP with the HTML form is rewritten in such way so that it's not brokenwhen the client has JS disabled (as you have now...), like below:
假设您的带有 HTML 表单的 JSP 以这种方式重写,以便在客户端禁用 JS 时它不会被破坏(就像您现在...),如下所示:
<form id="upload-form" class="upload-box" action="/Upload" method="post" enctype="multipart/form-data">
<input type="file" id="file" name="file1" />
<span id="upload-error" class="error">${uploadError}</span>
<input type="submit" id="upload-button" value="upload" />
</form>
Then it's with help of jQuery Form plugin just a matter of
然后它在jQuery Form插件的帮助下只是一个问题
<script src="jquery.js"></script>
<script src="jquery.form.js"></script>
<script>
$(function() {
$('#upload-form').ajaxForm({
success: function(msg) {
alert("File has been uploaded successfully");
},
error: function(msg) {
$("#upload-error").text("Couldn't upload file");
}
});
});
</script>
As to the servlet side, no special stuff needs to be done here. Just implement it exactly the same way as you would do when not using Ajax: How to upload files to server using JSP/Servlet?
至于servlet端,这里不需要做特别的事情。只需以与不使用 Ajax 时完全相同的方式实现它:如何使用 JSP/Servlet 将文件上传到服务器?
You'll only need an additional check in the servlet if the X-Requested-With
header equals to XMLHttpRequest
or not, so that you know how what kind of response to return for the case that the client has JS disabled (as of now, it are mostly the older mobile browsers which have JS disabled).
如果X-Requested-With
标头等于XMLHttpRequest
或不等于,您只需要在 servlet 中进行额外检查,以便您知道在客户端禁用 JS 的情况下返回什么样的响应(截至目前,它主要是较旧的移动设备)禁用 JS 的浏览器)。
if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
// Return ajax response (e.g. write JSON or XML).
} else {
// Return regular response (e.g. forward to JSP).
}
Note that the relatively new XMLHttpRequest
version 2 is capable of sending a selected file using the new File
and FormData
APIs. See also HTML5 File Upload to Java Servletand sending a file as multipart through xmlHttpRequest.
请注意,相对较新的XMLHttpRequest
版本 2 能够使用新的APIFile
和FormData
API发送选定的文件。另请参阅HTML5 文件上传到 Java Servlet并通过 xmlHttpRequest 将文件作为多部分发送。
回答by Memin
@Monsif's code works well if the form has only file type inputs, if the there are some other inputs other then file type, then they get lost. So, instead of copying each form data and appending them to FormData object, the original form itself can be given to the constructor.
如果表单只有文件类型输入,@Monsif 的代码运行良好,如果除了文件类型之外还有其他一些输入,那么它们会丢失。因此,不是复制每个表单数据并将它们附加到 FormData 对象,而是可以将原始表单本身提供给构造函数。
Regarding the @Monsif's code and https://www.new-bamboo.co.uk/blog/2012/01/10/ridiculously-simple-ajax-uploads-with-formdata/post, I came out with the following code which worked for me. I hope it helps someone else.
关于@Monsif 的代码和https://www.new-bamboo.co.uk/blog/2012/01/10/ridiculously-simple-ajax-uploads-with-formdata/帖子,我得出了以下代码为我工作。我希望它可以帮助别人。
<script type="text/javascript">
var files = null; // when files input changes this will be initiliazed.
$(function() {
$('#form2Submit').on('submit', uploadFile);
});
function uploadFile(event) {
event.stopPropagation();
event.preventDefault();
//var files = files;
var form = document.getElementById('form2Submit');
var data = new FormData(form);
postFilesData(data);
}
function postFilesData(data) {
$.ajax({
url : 'yourUrl',
type : 'POST',
data : data,
cache : false,
dataType : 'json',
processData : false,
contentType : false,
success : function(data, textStatus, jqXHR) {
alert(data);
},
error : function(jqXHR, textStatus, errorThrown) {
alert('ERRORS: ' + textStatus);
}
});
}
</script>
The html code can be something like following:
html 代码可能如下所示:
<form id ="form2Submit" action="yourUrl">
First name:<br>
<input type="text" name="firstname" value="Mickey">
<br>
Last name:<br>
<input type="text" name="lastname" value="Mouse">
<br>
<input id="fileSelect" name="fileSelect[]" type="file" multiple accept=".xml,txt">
<br>
<input type="submit" value="Submit">
</form>
回答by Monsif EL AISSOUSSI
This code works fine for me :
这段代码对我来说很好用:
$('#fileUploader').on('change', uploadFile);
function uploadFile(event)
{
event.stopPropagation();
event.preventDefault();
var files = event.target.files;
var data = new FormData();
$.each(files, function(key, value)
{
data.append(key, value);
});
postFilesData(data);
}
function postFilesData(data)
{
$.ajax({
url: 'yourUrl',
type: 'POST',
data: data,
cache: false,
dataType: 'json',
processData: false,
contentType: false,
success: function(data, textStatus, jqXHR)
{
//success
},
error: function(jqXHR, textStatus, errorThrown)
{
console.log('ERRORS: ' + textStatus);
}
});
}
<form method="POST" enctype="multipart/form-data">
<input type="file" name="file" id="fileUploader"/>
</form>
回答by Sameera Madushanka
This code works for me.
这段代码对我有用。
Used commons io.jar & commons file upload.jar and the jQuery form plugin
使用了 commons io.jar & commons 文件 upload.jar 和 jQuery 表单插件
<script>
$(function() {
$('#upload-form').ajaxForm({
success: function(msg) {
alert("File has been uploaded successfully");
},
error: function(msg) {
$("#upload-error").text("Couldn't upload file");
}
});
});
</script>
<form id="upload-form" class="upload-box" action="upload" method="POST" enctype="multipart/form-data">
<input type="file" id="file" name="file1" />
<span id="upload-error" class="error">${uploadError}</span>
<input type="submit" id="upload-button" value="upload" />
</form>
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (isMultipart) {
// Create a factory for disk-based file items
FileItemFactory factory = new DiskFileItemFactory();
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
try {
// Parse the request
List items = upload.parseRequest(request);
Iterator iterator = items.iterator();
while (iterator.hasNext()) {
FileItem item = (FileItem) iterator.next();
if (!item.isFormField()) {
String fileName = item.getName();
String root = getServletContext().getRealPath("/");
File path = new File(root + "../../web/Images/uploads");
if (!path.exists()) {
boolean status = path.mkdirs();
}
File uploadedFile = new File(path + "/" + fileName);
System.out.println(uploadedFile.getAbsolutePath());
item.write(uploadedFile);
}
}
} catch (FileUploadException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
enter code here