This question already has answers here:
How can I upload files to a server using JSP/Servlet and Ajax?
(4 answers)
Closed 6 years ago.
HTML
<div style="width:200px">
<form action="javascript:_bulkUser();" method="post" enctype="multipart/form-data">
Select File:<input type="file" name="fname"/><br/>
<input type="submit" value="upload"/>
</form>
</div>
js(ajax call)
_bulkUser : function(scope) {
try {
$.ajax({
type : "post",
url : "FileUploadServlet",
success : function(data) {
alert('Sucess');
},
error : function(data) {
console.log(data);
}
});
} catch (e) {
console.log(e);
}
}
Servlet
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
System.out.println("working");
MultipartRequest mp = new MultipartRequest(request, "e:/new");
out.print("successfully uploaded");
}
To the point, as of the current XMLHttpRequest version 1 as used by jQuery, it is not possible to upload files using JavaScript through XMLHttpRequest. The common workaround is to let JavaScript create a hidden 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).
Assuming that your JSP with the HTML form is rewritten in such way so that it's not broken when the client has JS disabled (as you have now...), like below:
<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
<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?
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).
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 Servlet and sending a file as multipart through xmlHttpRequest.
This code also 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>
Related
I have asp web page responsible of uploading file using ajax.
the html code of the form is:
<form method="post" action="ajax/firmwareUpload" enctype="multipart/form-data" id="uploadform" name="uploadform">
<div class="left">
<span id="lang502009" title="502009">Firmware File</span>:
<input name="download image file" id="uploadfilename" type="file">
</div>
<div class="right">
<div class="upload" id="uploadManual">
<input type="submit" class="button button-blank" value="Upload"/>
</div>
</div>
</form>
the ajax code is :
$("#uploadform").submit(function(e) {
$.ajax({
url: 'ajax/firmwareUpload',
type: 'POST',
data: new FormData(this),
processData: false,
contentType: false,
enctype: 'multipart/form-data',
success: function(data) {
if (data.error) {
$("body").load("subpage/upgradefail.asp");
setTimeout(backToIndex, 5*1000);
}
else {
var time = data.return;
$("body").load("subpage/upgradewait.asp");
setTimeout(backToIndex, time*1000);
}
},
error: function(data) {
alert("Operation could not be completed");
}
});
e.preventDefault();
});
This code works well as wanted for different browsers like firefox, chrome, safari, Opera. but I got problems with IE8 in the ajax response.
But the request works fine and can receive from the browser and send to the browser the response. But when IE8 receives the response it can't access to the success or error functions.
After a lot of searches I found in the internet that the problem is because IE8 have some problems with xhr communication. And the ajax code can be better with xdr.
My problem here is how I can convert my ajax code to xdr?
The problem especially is with processData, enctypes attributes and "new new FormData(this)". and is there modification that should be done in the tag form attributes?
I have one scenario: I am uploading one file at some server location using: https://www.playframework.com/documentation/2.0/JavaFileUpload ,
//Uploading file:
<input type="file" name="fileUpload">
<input type="submit" value="Upload">
And from the below code, I am uploading the above uploaded file and getting/displaying it on my view page like(After clicking the Submit button):
<input type="file" id="inputfile">
<input type="button" value="Submit" id="submitfile">
jQuery:
$("#submitfile").click(function(){
var path1 =$('input[type=file]').val().replace(/C:\\fakepath\\/i, '');//uploaded file names
//adding the Play framework server path for Application to get the image(s) file(s) path
var filespath = '/files/images/'+path1;//giving my uploaded files path here
});
But my requirement is that: I need only one type which does both: accepts/uploads the file at server location and returns/displays the same file path from server location on my view page ? I am struggling for it. Please help me.
This looks like a similar issue to 33163555. That question has the following example:
Edit: Reference 2320069 for support on ajax file uploads & alternatives:
FormData support starts from following desktop browsers versions. IE
10+, Firefox 4.0+, Chrome 7+, Safari 5+, Opera 12+
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<form enctype="multipart/form-data">
<input type="file" id="file" name="file" />
<input type="submit" id="submit" name="" value="Upload" />
</form>
<script>
$('#submit').click(function (event) {
event.preventDefault();
var file = $('#file').get(0).files[0];
var formData = new FormData();
formData.append('file', file);
$.ajax({
url: 'upload',
data: formData,
type: 'POST',
contentType: false,
processData: false,
beforeSend: function (data) {
alert('Are you sure you want to upload document?');
},
success: function (data) {
//call your jQuery action here
alert('Upload completed: ' + data);
},
error: function (jqXHR, textStatus, errorThrown) {
alert(textStatus + ': ' + errorThrown);
}
});
return false;
});
</script>
In your routes you have:
POST /upload controllers.Application.upload()
Where your controller method returns the filepath:
public static Result upload() {
MultipartFormData body = request().body().asMultipartFormData();
FilePart fileP = body.getFile("file");
if (fileP != null) {
File file = fileP.getFile();
//If we want to move from temp
//FileUtils.moveFile(file.getCanonicalPath(), "FileB");
return ok(file.getCanonicalPath());
} else {
return badRequest("Upload Error");
}
}
And you can perform your custom jQuery action in the ajax success callback
I am trying to use jQuery to trigger a form submission and then use AJAX to call a PHP script that will handle the file and return a response. The issue, though, is that the file is not being uploaded upon submitting the form.
HTML:
<div id="browseButton" class="step1Button" onclick="browseFile()">Browse</div>
<form method="post" id="fileForm" style="display:inline-block;">
<input id="browseInput" type="file" name="FileInput" style="display: none"/>
<label for="upload-click-handler"></label>
<input id="upload-click-handler" type="text" readonly />
<input id="submitForm" type="submit" style="display: none"/>
</form>
<div id="previewButton" class="step1Button pull-right" onclick="uploadFile()" style="background-color: #57a957">
Preview
</div>
jQuery:
function uploadFile() {
submitForm();
parseExcel();
}
var submitForm = function() {
$('#previewButton').click(function(){
$('#submitForm').click();
});
};
var parseExcel = function() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET",'default/ParseExcel',true);
xmlhttp.send();
console.log("made it past excel parse");
};
The PHP that's called:
public function actionParseExcel() {
print "made it to parse".PHP_EOL;
print "File:";
if($_FILES['FileInput']['tmp_name']) {
print_r($_FILES['FileInput']['tmp_name']);
}
else {
print "Not found";
}
print "Done.";
}
I know the issue is that my form isn't submitting the chosen file because that's typically why the "Undefined index" error is thrown. But I can't understand why.
First, if you don't want your page to refresh, you better use <input type="button">
or else call your JavaScript via <form onSubmit="uploadFile()"> and return false at the end of your function uploadFile().
Second, you'll need to put enctype="multipart/form-data" in your <form>.
I see you're using JQuery, you should use it to send your AJAX request too :
// This code supports multiple type="file" inputs
// Variable to store your files
var files;
// Add events
$('input[type=file]').on('change', prepareUpload);
// Grab the files and set them to our variable
function prepareUpload(event)
{
files = event.target.files;
}
// Create a formdata object and add the file
var data = new FormData();
// In case you want to upload more than one file
$.each(files, function(key, value)
{
data.append(key, value);
});
$.ajax({
url: 'your.php?FileInput',
type: 'POST',
data: data,
cache: false,
dataType: 'json',
processData: false, // Prevent the file from beeing converted to string
contentType: false, // Set the content file to false prevent JQuery from using 'application/x-www-form-urlencoded; charset=UTF-8' as default type
...
});
I hope this will lead you to the solution...
Edited : var files declaration + files processing
To send forms with files you need to use enctype="multipart/form-data".
BUT, as far as I know, you can't send files using ajax.
So, the solution for that is to use a hidden iFrame:
Create a hidden iFrame (outside of your form) and assing it an ID
Create the form pointing to yout PHP file, and using the attribute enctype="multipart/form-data" and target="ID_OF_THE_IFRAME" (so the form, when submitted, will be sent to that iframe)
When the PHP finish procesing the file, you could output a javascript that calls parent.YOURFUNCTION(), so you can do whatever you want when the process is done.
Good luck!
I have been attempting to get a nice neat file upload using ajax, and from the many items on SO I have been able to get the framework done as follows:
My HTML:
<form enctype="multipart/form-data" method="post">
<input name="file" type="file" />
<input type="button" value="Upload" />
Pretty straight forward.
My PHP storeSales.php
if ($_FILES["file"]["name"] != NULL) {
if (file_exists("accounting/" . $_FILES["file"]["name"])){
echo $_FILES["file"]["name"] . " already exists. ";
}else{
move_uploaded_file($_FILES["file"]["tmp_name"], "accounting/" . $_FILES["file"]["name"]);
}
}
$file = fopen($_FILES['myfile']['name'],'r') or die('cant open file');
and my .js:
$(":button").click(function(){
var formData = new FormData($('form')[0]); if (formData !=null) {
alert("Got the file");
} else {
alert("nothing Here");
}
$.ajax({
url: 'storeSales.php', //Server script to process data
type: 'POST',
xhr: function() { // Custom XMLHttpRequest
var myXhr = $.ajaxSettings.xhr();
if(myXhr.upload){ // Check if upload property exists
myXhr.upload.addEventListener('progress',progressHandlingFunction, false); // For handling the progress of the upload
}
return myXhr;
},
//Ajax events
success: function(result)
{
console.log($.ajaxSettings.xhr().upload);
alert(result);
},
// Form data
data: formData,
//Options to tell jQuery not to process data or worry about content-type.
cache: false,
contentType: false,
processData: false
});
});
function progressHandlingFunction(e){
if(e.lengthComputable){
$('progress').attr({value:e.loaded,max:e.total});
}
}
When I try to upload a file, I get the alert in my .js file that says "Got the file" but in the php code I get the error that a file cannot be empty. From everything I have been able to find, I thought I was doing the php correctly. what is the correct way to handle this? Am I missing something else?
You can't use ajax to upload files - it's an illegal operation (via the dry Ajax route) without a third-party script. In short, you can't pass $_FILES data via Ajax. Only $_POST data. You need to find a plugin.
Try Uploadify:
http://www.uploadify.com/
I've figured out how to upload a file using AJAX and Flask such that the page doesn't refresh and the file is uploaded to the server in some specified directory.
In the Python method (upload()), I want to process the filename with some regex and return an array to the Javascript file.
Do I still return render_template(index.html), even if I'm trying to request an array?
HTML (index.html)
<form id="upload-file" role="form" action="sendQuestions" method="post" enctype="multipart/form-data">
<div class="modal-body">
<label for="file"><b>Upload packet here</b></label>
<input type="file" name="file">
<p class="help-block">Upload a .pdf or .docx file you want to read.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button id="upload-file-btn" type="button" class="btn btn-primary" data-dismiss="modal" value="Upload">Upload</button>
</div>
</form>
Javascript
$(function() {
$('#upload-file-btn').click(function() {
var form_data = new FormData($('#upload-file')[0]);
$.ajax({
type: 'POST',
url: '/uploadajax',
data: form_data,
contentType: false,
cache: false,
processData: false,
async: false,
success: function(data) {
console.log('Success!');
},
});
});
});
Python (Flask)
#app.route('/uploadajax', methods=['POST'])
def upload():
file = request.files['file']
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return render_template('index.html')
I'm playing around with adding this AJAX call in the Javascript after the $.ajax{} part, but did I do it right? I'm not sure if I can call the same Python method twice in one Javascript function, or if there's an entirely better way to do this.
ajaxRequest = ajaxFunction()
ajax.onreadystatechange = function() {
if (ajaxRequest.readyState === 4) {
if (ajaxRequest.status === 200) {
alert(ajaxRequest.responseText) //I want the Python to put the array into this ajaxRequest.responseText variable, not sure how.
}
else
alert('Error with the XML request.')
}
}
ajaxRequest.open("GET", 'uploadajax', true);
ajaxRequest.send(null);
Any help? Thanks.
You don't say what you want to achieve (hide some div, scroll window ...), and that's a main problem. To sum what should be done :
Don't return
return render_template('index.html')
but fe. if you want to notify the user about the upload status, make status for this call like
return Response('OK')
or other status - NOTOK or something.
Then in the js :
success: function(data) {
console.log('Success!');
},
manipulate the response
if (data == 'OK') {
alert ('YAY, FILE UPLOADED');
};