Since most topics about this subject are over a year old, I asked myself if there are any good solutions to track an ajax progress event from an http service (for a loading bar or to track how many bytes it has downloaded). Without the use of 3rd parties :)
these events:
var ajax = new XMLHttpRequest();
ajax.addEventListener("progress")
ajax.addEventListener("load")
ajax.addEventListener("error")
ajax.addEventListener("abort")
I've made something like that using a promise with notify for the progress :
var deferred = $q.defer();
var fd = new FormData();
fd.append("Filename", file.name);
fd.append("file", file);
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", function (event) {
deferred.notify(event);
}, false);
xhr.addEventListener("load", function (data) {
deferred.resolve(event.target.response);
}, false);
xhr.addEventListener("error", function (data) {
deferred.reject(event.target.response);
}, false);
xhr.addEventListener("abort", function (data) {
deferred.reject(event.target.response);
}, false);
xhr.open("POST", URL);
xhr.send(fd);
return deferred.promise;
Related
I'm uploading files using the following code:
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", uploadProgress, false);
xhr.open("POST", requestUrl, true);
xhr.send(f);
Note that I'm attaching a listener to upload progress:
function uploadProgress(evt)
{
// Which upload was it?
}
Here's the question, if I have multiple uploads happening at the same time, and they are sharing the same event handler, how can I figure out which upload triggered the event?
Try to wrap it as a Control?
var uploadProgress = function(uploadObj, event) {
// Do somthing about uploadObj
}
// Target maybe object or string, whatever you want
var Uploader = function(target) {
var xhr = new XMLHttpRequest();
var handler = uploadProgress.bind(this, target);
xhr.upload.addEventListener("progress", handler, false);
xhr.open("POST", target, true);
xhr.send(f);
}
The .bind will return a new function, when execute the new function, it'll:
Use this here, the Uploader as its context.
Execute uploadProgress and pass target as first argument, so the evt given by progess event will be passed to the 2nd param in uploadProgress.
I am working on Titanium Appcelerator to develop iphone application. I need to call a web service with different parameters about more than 1250 times. I have place the xhr.send() method inside the xhr.onload function. It working fine about 3-8 times but stop calling after that. No error or any issues displaying there. Please suggest.
function(e){
var xhr = Titanium.Network.createHTTPClient();
var Request = "<RefId>"+idArray[e.index]"</RefId>";
xhr.open("POST", url);
xhr.setRequestHeader("WWW-Authenticate","Basic");
xhr.setRequestHeader("Content-Type","text/xml", "charset=utf-8");
xhr.setRequestHeader("Content-Length", Request.length);
xhr.setRequestHeader("SOAPAction", "http://example.com");
xhr.onload = function() {
var doc = Titanium.XML.parseString(this.responseText);
var type = doc.getElementsByTagName("studentName");
Ti.API.info(type.item+';'+type.item.length);
if(type.item.length<1){
file = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory, "textfile.txt");
}
doc=null;
type=null;
if(idArray.length>e.index){
//alert('Calling API');
var url="http://example.com";
var Request = "<RefId>"+idArray[e.index++]"</RefId>";
xhr.setTimeout(2500);
xhr.open("POST", url);
xhr.send(Request);
}
};
xhr.onerror = function(){
alert('Error')
};
xhr.send(Request);
}
I would try recreating the client each time not just calling send again
I'm making crossdomain ajax post request.
There is the client function:
function getUsersData()
{
var ids = ["user1_id", "user2_id"];
var fd = new FormData();
$.each(ids, function() {
fd.append('identities', this);
});
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://some-domain.com/Home/GetUsersData', true);
xhr.withCredentials = true;
xhr.onreadystatechange = responseHandler; //function is defined and not shown here
xhr.send(fd);
}
Everything works fine in Opera and Google Chrome browsers.
But Firefox says NS_ERROR_CANNOT_CONVERT_DATA: Component returned failure code: 0x80460001 (NS_ERROR_CANNOT_CONVERT_DATA) [nsIDOMFormData.append] at the line fd.append('identities', this);
What it can be and how to fix this error?
Try to use unique keys. Something like: fd.append('identity-'+this.id, this);
i have a signle html element which i need to show and hide by jquery into a pure javascript xhr request method, for now it shows always the element without hiding when request is complete/success, on error i would like to hide that again.
html
<div class="ajax-loading">Loading ..</a>
xhr method
function post(_url, _callback,_data){
var xhr = createCORSRequest('POST',_url);
if (!xhr){
throw new Error('CORS not supported');
}
$('.ajax-loading').show();
xhr.send(_data);
/*SUCCESS -- do somenthing with data*/
xhr.onload = function(){
// process the response.
_callback(xhr.responseText);
$('.ajax-loading').hide();
};
xhr.onerror = function(e){
console.log(e);
$('.ajax-loading').show();
};
}
the problem is that i always do that by $.ajax() statements(error,success,beforeSend), this time i have pure javascript xhr requests and i don't know how to do that.
to be more clear i would like this converted to xhr javascript as shown:
$.ajax({
/*data etc ...*/
error:function(){
$('.ajax-loading').show();
},
success:function(){
$('.ajax-loading').hide();
},
beforeSend:function(){
$('.ajax-loading').show();
}
});
EDITED
i tryed also without success:
function get(_url, _callback){
var xhr = createCORSRequest('GET',_url);
if (!xhr){
throw new Error('CORS not supported');
}
xhr.send();
xhr.onreadystatechange = function() {
if(xhr.readyState == 4 /*COMPLETE STATEMENT*/){
alert(xhr.readyState);
}
};
/*SUCCESS -- do somenthing with data*/
xhr.onload = function(){
// process the response.
_callback(xhr.responseText);
};
xhr.onerror = function(e){
console.log(e);
};
}
Check this one:
Wiki for xmlhttprequest
In the xmlHTTPRequest you have to check the state of the object to find out what is going on with the request.
fixed with
xhr.onloadstart = function(){
$('.ajax-loading').show();
}
xhr.onloadend = function(){
$('.ajax-loading').hide();
}
I'm using FormData to ajax a file upload. The upload works, but the problem is that the "error" callback is never invoked. Even when my HTTP response is a 500 internal server error (to test this I tweak server to respond with 500), the "load" callback is invoked.
function upload_image() {
var form = document.getElementById('upload_image_form');
var formData = new FormData(form);
var xhr = new XMLHttpRequest();
xhr.addEventListener("load", function(e) {
alert("Success callback");
}, false);
xhr.addEventListener("error", function(e) {
alert("Error callback");
}, false);
xhr.open("POST", "/upload_image");
xhr.send(formData);
}
Any ideas? I'm testing this on Chrome.
This setup should work better for your needs:
var req = new XMLHttpRequest();
req.open('POST', '/upload_image');
req.onreadystatechange = function (aEvt) {
if (req.readyState == 4) {
if(req.status == 200)
alert(req.responseText);
else
alert("Error loading page\n");
}
};
req.send(formData);
In your code error callback is never called because it is only triggered by network-level errors, it ignores HTTP return codes.
The load event is called whenever the server responds with a message. The semantics of the response don't matter; what's important is that the server responded (in this case with a 500 status). If you wish to apply error semantics to the event, you have to process the status yourself.
Expanding on #rich remer's answer, here's how you could access the status yourself:
function upload_image() {
var form = document.getElementById('upload_image_form');
var formData = new FormData(form);
var xhr = new XMLHttpRequest();
xhr.addEventListener("load", function(e) {
if(e.currentTarget.status < 400)
alert("Load callback - success!");
else
alert("Load callback - error!");
}, false);
xhr.addEventListener("error", function(e) {
alert("Error callback");
}, false);
xhr.open("POST", "/upload_image");
xhr.send(formData);
}
Please note accessing of the e.currentTarget.status property of the response event (e). Looks like the status is actually available via any of e.{currentTarget,target,srcElement}.status - I'm not sure which one should be used as the best practice, though.
function get(url) {
return new Promise(function(succeed, fail) {
var req = new XMLHttpRequest();
req.open("GET", url, true);
req.addEventListener("load", function() {
if (req.status < 400)
succeed(req.responseText);
else
fail(new Error("Request failed: " + req.statusText));
});
req.addEventListener("error", function() {
fail(new Error("Network error"));
});
req.send(null);
});
}
code from EJS
by the example code
it is clear that network error has no response, it trigger error event.
response trigger load event
and you have to decide what to do with the response status