I've been noodling with an XMLHttpRequest to update users on upload progress for large files in a web form:
function progressHandler(event) {
var percent = Math.round((event.loaded / event.total) * 100);
$('#loader').text( percent + '%' );
}
$("#Submit").click(function () {
var file = document.getElementById('fileupload').files[0];
var formData = new FormData(document.getElementById("new-job-form"));
ajax = new XMLHttpRequest();
ajax.upload.addEventListener("progress", progressHandler, false);
ajax.onreadystatechange = function () {
if (ajax.readyState == 4 && ajax.status == 200) {
// we'll come back to this
}
}
ajax.open("POST", "#Url.Action("NewJob", "Home")");
ajax.send(formData);
});
And this works fine, up until the point the load completes.
My web application backend is written in .Net MVC and originally used this after the file upload was complete:
return RedirectToAction("FieldMapping", new { jobId = job.JobId });
This no longer works, because I've made the call asynchronous by invoking XMLHttpRequest.
The alternative is to return Json containing the target Url and redirect to that. This is a pain, and I'm having trouble getting it work properly. There are a few questions about this already on SO and the consensus is: don't do this. The whole point of Ajax is deal with partial responses, not whole-page redirects.
Which I understand, but I don't know of another way I can monitor the progress of a file upload and send it back to the user without using XMLHttpRequest. Is there another way to approach this, so I can just RedirectToAction after the request is complete?
I think you are looking for this: Using XMLHttpRequest
Progress events exist for both download and upload transfers. The download events are fired on the XMLHttpRequest object itself, as shown in the above sample. The upload events are fired on the XMLHttpRequest.upload object, as shown below:
var oReq = new XMLHttpRequest();
oReq.upload.addEventListener("progress", updateProgress);
oReq.upload.addEventListener("load", transferComplete);
oReq.upload.addEventListener("error", transferFailed);
oReq.upload.addEventListener("abort", transferCanceled);
oReq.open();
Why not do your "redirect" in the "load" event handler, which lets you know that the upload is finished? You could also use this:
One can also detect all three load-ending conditions (abort, load, or error) using the loadend event:
req.addEventListener("loadend", loadEnd);
function loadEnd(e) {
console.log("The transfer finished (although we don't know if it succeeded or not).");
}
Related
I'm currently building a website that uses AJAX to dynamically update sections of the page without the need to refresh, however, when I change aspects of the file that AJAX reads the website sometimes takes minutes to update even though the file is read about once per second. Whilst looking for the issue I found that I can turn caching off by using the developer tools and this then allowed the website to update at the appropriate speed.
Here's the code I am using:
var path = "Path of the json file i am reading"
var state;
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
state = JSON.parse(this.responseText);
}
};
xhttp.open("GET", path, true);
xhttp.send();
I've been looking for a while now and the only advice I can see about what to do about the cache is to use the developer tools to turn it off. Is there any way I can implement some code to automatically tell the browser to not cache the file being read?
I am trying to create a temporary image url for a local image and send it to Google to do a Search by Image. I don't want the image url to be permanent so I want to delete it right after I use it. I have the code below:
// Gets a URL that can be used to do a search by image through Google.
function getImageURL() {
var xml = new XMLHttpRequest();
xml.onreadystatechange = function () {
if (xml.readyState == 4 && xml.status == 200) {
deleteImageURL(); // asynchronous call to server to delete the URL
window.location.href =
"https://www.google.com/searchbyimage?site=search&sa=X&image_url="
+ xml.responseText; // the image url
}
}
xml.open("GET", "REST_ENDPOINT", true);
xml.send();
}
The function above calls the server, and when it finishes, will delete the url and redirect the page. The function "deleteImageURL()" is another ajax call done asynchronously. Currently, this loads the google page fine as the image URL is not done deleting the url by the time that the redirect happens.
My question is this: Will deleteImageURL() finish deleting the image URL even after the page redirects or will it stop (and thus, never delete the URL)?
EDIT: So I was thinking about what you guys were saying about race conditions and tried the following code instead:
// Gets a URL that can be used to do a search by image through Google.
function getImageURL() {
var xml = new XMLHttpRequest();
xml.onreadystatechange = function () {
if (xml.readyState == 4 && xml.status == 200) {
deleteImageURL(xml.responseText);
}
}
xml.open("GET", "REST_ENDPOINT"
+ id + "/public_url", true);
xml.send();
}
// Deletes the url for the image.
function deleteImageURL(imageURL) {
var xml = new XMLHttpRequest();
xml.open("GET", "REST_ENDPOINT_FOR_DELETE", true);
xml.send();
window.location.href =
"https://www.google.com/searchbyimage?site=search&sa=X&image_url="
+ imageURL;
}
This code works every time that I run it. I think that there still may be a race condition, but it seems to be working fine so far.
Thanks again.
The "deleteImageURL()" will finish deleting the image URL even after the page redirects..
Refer : Should I wait for ajax to complete to redirect a page?
The server won't stop processing the request (initiated by deleteImageUrl), but you will not be able to handle a callback if the current page unloads in the browser before the operation is completed.
If deleteImageURL(); contains an async call you should do the redirect when the call is completed. Your code will work when the call is synchronious. We don't see the source of deleteImageURL(); and can be more concrete, but you should do the same thing as you've done for getImageURL().
I've been working with phonegap to build an app and have been using ajax to communicate with the server to get all the necessary data. Some of the pages take a few seconds to load (and I dont display the page until everything is loaded) and I would like a loading screen to appear while the client is communicating with the server and processing all the data.
I had everything working great until I decided to throw the the ajax calls into functions (I'm working with a few team members, so I thought it would be easier for them to use these ajax calls if they were in some nice functions). Now because of the ajax function is asynchronous, the loading screen turns on and off before the requests are finished processing. I would like my function to stop the execution of code (similar to an alert) so that the loading screen will turn off AFTER all the ajax calls are made.
Essentially I want my javascript code to look like this:
loading();
sendRequests();
notLoading();
where loading() displays the loading screen, and notLoading() turns the loading screen off. My sendRequests() function is specific to each page (each page has to send different requests depending on the functionality of the page)
if you guys are wondering what the loading() and notLoading() functions looks like, here you go
// functions to make loading screen appear and disappear
function loading() {
document.getElementById("blackout").style.display = 'block';
}
function notLoading() {
document.getElementById("blackout").style.display = 'none';
}
I looked into a few other posts about it
How to wait for ajax request to complete in javascript when synchronous option is not available?
http://www.hunlock.com/blogs/Snippets:_Synchronous_AJAX
Which those two links essentially tell you the same information, that the third parameter in request.open() needs to be set to false... well, I've tried that and it didn't work =/
here is an example of my getRequest() function so everyone can see what I'm trying to do:
// will send a GET request to the parameter url
function getRequest(url) {
var req = new XMLHttpRequest();
req.open('GET', url, false);
setHeaders(req);
req.onreadystatechange = function() {
if (req.readyState == 4) {
if( (req.status == 200) || (req.status == 0) ) {
if( (typeof req.responseText != "undefined") && (req.responseText != "") ) {
localStorage["request"] = req.responseText;
}
else {
alert("GR: Error talking to the server");
}
}
else {
alert("GR: Error talking to server");
}
}
}
req.send(null);
return parseJSON();
}
If anyone knows how I can fix this, I would be very appreciative!
I ended up just throwing the notLoading() function at all the exit statuses in the sendRequests() function. Kind of a pain, but seems to work now.
I' m using this code in my mobile application built with phonegap and jQuery I want to show pictures from server but I couldn't integrate showPageLoadingMsg function and I 'm not convinced that this type of Ajax call is useful and powerful. So I want really know what type of Ajax call I should use and how to use showPageLoadingMsg() function in my Android phone application .
server = "http://monserveur.com/upload.php";
var wid = $(window).width();
if (server) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange=function(){
if(xmlhttp.readyState == 4){
alert('ready');
if (xmlhttp.status == 200 ) {
alert('200');
document.getElementById('ousa').innerHTML = xmlhttp.responseText;
}
else {
document.getElementById('ousa').innerHTML = "Error retrieving pictures from server.";
}
}
};
xmlhttp.open("GET", server+"?wid="+wid, true);
xmlhttp.send();
Have you tried
http://api.jquery.com/ajaxStart/
http://api.jquery.com/ajaxStop/
and couple them with a logic like found here
http://www.w3schools.com/jquery/ajax_ajaxstart.asp
$("div").ajaxStart(function(){
$(this).html("<img src='demo_wait.gif' />");
})ajaxStop(function(){
$(this).empty();
});
This will basically add a listener if added to a self executing function or the dom ready logic of your script this listener will wait for anything ajax related to run.
$.post()
$.get()
$.ajax()
$.getJSON()
$.postJSON()
//any I missed?
also I notice you mention phonegap, are you currently using the xhr.js they suggest using with AJAX requests? If not its something I suggest looking into, due to the same domain policy your AJAX may just be failing silently and very quickly. the xhr.js over comes the bounds of the same domain policy.
I want to create a website which loads a image via XMLHttpRequest(). (XMLHttpRequest because I want to represent the user a % progressbar)
My Code:
var req = new XMLHttpRequest();
req.addEventListener("progress", onUpdateProgress, false);
req.addEventListener("load", onTransferComplete, false);
req.addEventListener("error", onTransferFailed, false);
req.addEventListener("abort", onTransferFailed, false);
req.open("GET", "image.png", true);
req.send();
function onUpdateProgress(e) {
if (e.lengthComputable) {
var percent_complete = e.loaded/e.total;
if (Math.round(percent_complete*200)>=20) {
$("#progress").animate({
width: Math.round(percent_complete*100)
}, 0);
}
}
}
function onTransferFailed(e) {
alert("Something went wrong. Please try again.");
}
function onTransferComplete(e) {
//Problem
}
My problem is I donĀ“t know how to show the image which is now loaded. I hope anyone can help me :) Thanks ...
You can do this using DATA URIs, but it's hard to make that work in all current browsers.
If caching options are set correctly, you can better load it twice: first using your AJAX request, then, after the image has been cached by the browser, another time using the usual image functions. The second time your image will not be retrieved from the server again, but the browser will use the cached file and show the image almost instantly.