AJAX Newbie , POSTing data on server - ajax

I started learning AJAX recently and am trying a very simple project which involves capturing some form data and sending it to two servers.
The first server is the one which hosts the website and server side php handling. This worls fine
The second server is a python basic http server which handles only the POST operation request send from AJAX. This functionality works but is a bit weird.
Let me explain
Here is my AJAX code which is absolutely straight forward.
function xml_http_post(url, data) {
var req = false;
try {
// Firefox, Opera 8.0+, Safari
req = new XMLHttpRequest();
}
catch (e) {
// Internet Explorer
try {
req = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e) {
try {
req = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e) {
alert("Your browser does not support AJAX!");
return false;
}
}
}
req.onreadystatechange = function() {
if (req.readyState == 4) {
// callback(req);
}
}
req.open("POST", url, true);
req.setRequestHeader("Content-type","text/plain");
req.send(data);
}
Since I do not intend to send back any response , my callback function on ready state change is empty.
But when I execute this code ( triggered by onclick on a button) , the POST doesnt work and server doesnt seem to receive anything.
But the most surprising thing is that if I keep a breakpoint at req.open( ) and then do a manual step execution then it works always. Which means , I guess that there is some timing issue which needs to be resolved.
It works fine without breakpoints if the third parameter "async" is set to false but that is anyway undesirable so I want to make it work with async = true.
Any help would be greatly appreciated.
Thanks
Shyam

As I figured out, the form page was getting unloaded by a php script which was invoked as a action of the form b the first server. This resulted in the javascript code being partially or not executed.
So I figured out that sync XHR is the only way for my.

Related

can't seem to get progress events from node-formidable to send to the correct client over socket.io

So I'm building a multipart form uploader over ajax on node.js, and sending progress events back to the client over socket.io to show the status of their upload. Everything works just fine until I have multiple clients trying to upload at the same time. Originally what would happen is while one upload is going, when a second one starts up it begins receiving progress events from both of the forms being parsed. The original form does not get affected and it only receives progress updates for itself. I tried creating a new formidable form object and storing it in an array along with the socket's session id to try to fix this, but now the first form stops receiving events while the second form gets processed. Here is my server code:
var http = require('http'),
formidable = require('formidable'),
fs = require('fs'),
io = require('socket.io'),
mime = require('mime'),
forms = {};
var server = http.createServer(function (req, res) {
if (req.url.split("?")[0] == "/upload") {
console.log("hit upload");
if (req.method.toLowerCase() === 'post') {
socket_id = req.url.split("sid=")[1];
forms[socket_id] = new formidable.IncomingForm();
form = forms[socket_id];
form.addListener('progress', function (bytesReceived, bytesExpected) {
progress = (bytesReceived / bytesExpected * 100).toFixed(0);
socket.sockets.socket(socket_id).send(progress);
});
form.parse(req, function (err, fields, files) {
file_name = escape(files.upload.name);
fs.writeFile(file_name, files.upload, 'utf8', function (err) {
if (err) throw err;
console.log(file_name);
})
});
}
}
});
var socket = io.listen(server);
server.listen(8000);
If anyone could be any help on this I would greatly appreciate it. I've been banging my head against my desk for a few days trying to figure this one out, and would really just like to get this solved so that I can move on. Thank you so much in advance!
Can you try putting console.log(socket_id);
after form = forms[socket_id]; and
after progress = (bytesReceived / bytesExpected * 100).toFixed(0);, please?
I get the feeling that you might have to wrap that socket_id in a closure, like this:
form.addListener(
'progress',
(function(socket_id) {
return function (bytesReceived, bytesExpected) {
progress = (bytesReceived / bytesExpected * 100).toFixed(0);
socket.sockets.socket(socket_id).send(progress);
};
})(socket_id)
);
The problem is that you aren't declaring socket_id and form with var, so they're actually global.socket_id and global.form rather than local variables of your request handler. Consequently, separate requests step over each other since the callbacks are referring to the globals rather than being proper closures.
rdrey's solution works because it bypasses that problem (though only for socket_id; if you were to change the code in such a way that one of the callbacks referenced form you'd get in trouble). Normally you only need to use his technique if the variable in question is something that changes in the course of executing the outer function (e.g. if you're creating closures within a loop).

With JavaScript Ajax polling for widget

I have the follow problem. I need to create a JS widget and set it on one blog, for example any blog from blogger.com. YOu can select there a box for javascript and I will post the JS in this box.
The problem what I have and don't know how to do this is, that the script should do an ajax polling for exmaple for 60 seconds. But how to execute an ajax call, when the host is not the same linke the host, where the JS is includet?
For example the easiest way to explai is: There is a search box and when enayone searches for anythign, then the JS script should streaming the results for 60 seconds from the server what I have set in the script and is different as the host, where the JS is includet, without to become a problem with the JS restriction for hosts.
Or for example a chat client, where the client is hosted on one other host and the server on another.
Can anyone tell me an idea, or send me an example how to do this?
Thanks
Nik
Well with this example is it possible but without JSONP?
function asyncreq(url) {
var xmlhttp = false;
try {
xmlhttp = new XMLHttpRequest();
} catch (trymicrosoft) {
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (othermicrosoft) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
xmlhttp = false;
}
}
}
if (xmlhttp){
try {
xmlhttp.open("GET", url);
xmlhttp.onreadystatechange=function() {
document.getElementById('mydiv').innerHTML = xmlhttp.responseText;
}
xmlhttp.send(null);
}
catch (failed) {
xmlhttp = false;
}
}
}
If you send the response in chunks, then everything is fine. But here is the call in ajax again. And when I use it in a different host, then I can't call the url because of the same-origin policy.
Is there another way?
I found a very interesting example here.
Take a look at the bottom, there is a job search box. If you investigate a litte bit, then you will see there is a usage of a class RSL() which is doing the request. How this class is doing the request without ajax? I can't understand wow this class works. Can anyone show me a better example?
There are two main options:
Put an iframe where you want the widget to go. Its src URL would be on the same server that will receive the AJAX call.
Use JSONP, which consists of inserting a script tag into the page to bypass the same-origin policy. This requires that the AJAX server wrap its JSON output in ?(...), where the URL includes callback=?. Then, as soon as a response has been received, start another request.

XDomainRequest object caching/asynchronous call issue

I have an aspx page on which I am using XDomainRequest object to populate two div(s) with html returned from AJAX response.
I have used Jquery to get the divs and perform "each()" on the retrieved List
var divs = $("div");
divs.each(function(index) {
if (window.XDomainRequest) {
xdr = new XDomainRequest();
if (xdr) {
xdr.onload = function() {
alert("XDR Response - " + xdr.responseText);
var currentDivID = divs[index].attributes["id"].value;
var selectedDiv = $("div[id='" + currentDivID + "']");
if (xdr.responseText == '') selectedDiv.attr("style", "display:none;");
else selectedDiv.append(xdr.responseText);
};
xdr.open("GET", xdrUrl);
try {
xdr.send();
} catch (e) {
alert(e);
}
} else {
alert('Create XDR failed.');
}
} else {
alert('XDR not found on window object .');
}
}
Now, whats happening is , i have two Divs on a page that have different IDs and when this code runs on "$.ready(function(){})" , both requests are asynchronously sent to the server and processed
the result is
1. sometimes the onload get the response for the second div in both div results.
2. IE sents only one request to the server(I am using fiddler to see what requests are sent to server).
Can anybody guide me whats wrong with the code ? As far as I know XDR does not support synchronous calls, and asynchronous calls are giving me wrong results. Any workaround/tip for this problem.
Issue solved by myself when I pointed out a mistake in my code:(.
xdr = new XDomainRequest();
should be
var xdr = new XDomainRequest();
For Point 2 , I added "Cache-Control:no-cache" header in my response and it solved the matter.

Problem with Ajax submission?

I am using Ajax to post data to the server(PHP code) and update it. i am posting many data one after the other, but in between the Ajax post fails and dont return a readyState to 4.
the code is as follows
function getHttpRequest()
{
var request=false;
if(window.XMLHttpRequest)
{
request=new XMLHttpRequest();
}
else if(window.ActiveXObject)
{
try
{
request=new ActiveXObject("Msxml2.XMLHTTP");
}
catch(e)
{
try
{
request=new ActiveXObject("Microsoft.XMLHTTP");
}
catch(e)
{
request=false;
}
}
}
return request;
}
the code begins here..
function updateAnswer(){
var request=getHttpRequest();
request.open('post','addAnswer.php');
request.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
request.send("answer="+ans);
if(request.readyState == 4)
{
var response=request.responseText;
document.getElementById("display").innerHTML=response;
}
}
i call this function to update answer in database but it donot return status=4 sometimes... please help
innerinnerHTML should be innerHTML. updateAnswer gets called each time readyState is changing from zero to four. Four is fully loaded, while those lesser are different loading stages.
Why not make life easier and use a framework like jQuery?
Also, can't you post all the data at once, in that way save a few roundtrips to the server?

Delete htaccess credentials in Safari

I have an app that logs in via .htaccess. When the person wants to logout, I use:
function logout2()
{ try{
var agt=navigator.userAgent.toLowerCase();
if (agt.indexOf("msie") != -1) {
// IE clear HTTP Authentication
document.execCommand("ClearAuthenticationCache");
}
else {
var xmlhttp = createXMLObject();
xmlhttp.open("GET",".force_logout_offer_login_mozilla",true,"logout","");
xmlhttp.send("");
xmlhttp.abort();
}
} catch(e) {
alert("there was an error");
}
function createXMLObject() {
try { if (window.XMLHttpRequest) { xmlhttp =
new XMLHttpRequest(); } // code
for IE else if
(window.ActiveXObject) {
xmlhttp=new
ActiveXObject("Microsoft.XMLHTTP");
} } catch (e) { xmlhttp=false }
return xmlhttp;
}
The problem is that this is not working for Safari, the person is always logged in using the initial credentials, even closing and reopening the browser. Does anybody know how to handle this?
It is an undocumented quirk of Mozilla's XMLHttpRequest implementation that sending bad auth in an XMLHttpRequest affects the auth used by the main browser in the future. Leveraging this to provide logout is a reasonable hack for now, but I wouldn't count on it working in the future, let alone on other browsers.
The only reliable cross-browser way I know of to allow a logout function is to redirect the user to a page that will 401 them when they pass in valid auth credentials, instead of invalid ones. Then a logged-in user will be greeted with an auth prompt, which they can put bad auth in (normally you tell them to just leave the user/pass fields blank). The script responds positively (eg 302) to the bad auth and the browser remembers it for the future, overwriting the previous good auth.
Unfortunately this process does require some significant user interaction. This is one of the drawbacks of HTTP Authentication.

Resources