Comet, Tomcat and READ events - ajax

Trying to get my way trought Comet with Java servlets, I encountered a big problem: There seems to be no way to use the established connection to the client to send the server additional data from the browser (works in plain java when writing to the inputstream).
Following problem arises for a CometChat application when a Client connects to servlet, receives a form for sending input and a form for presenting server output: Now if the client wants to send some data at this connection, resulting in a READ event at the servlet, how can this be done?
I tried sending GET, HEAD and POST. With HEAD the comet connection is closed afterwards. GET always produces END, BEGIN and POST produces BEGIN, READ.
I tried searching the web, but the only answer I found was: Comet READ events are generating when there is a POST method with a body
How can I achieve this?
I'm using plain Javascript Ajax:
function send(content) {
var text = document.controller.input.value;
params = 'input=' + content;
var ajaxObj = createXMLHttp();
ajaxObj.open('POST', 'CometChat', true);
ajaxObj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
ajaxObj.setRequestHeader('Content-Length', params.length);
ajaxObj.setRequestHeader('Connection', 'close');
ajaxObj.onreadystatechange = function() {};
ajaxObj.send(params);
}
This produces BEGIN, READ. What headers do I need to set to produce a solely READ event only?
I'm able to 'cheat' this by looking up my connections and reuse response, but on client side, the AJAX request stays in interactive mode (although flushing it on the server) and I'm only able to may 5 requests on FF and 10 requests on IE before the following request is not processed. Also as soon as the first AJAX request is received on the server, I'm get TIMEOUT events, two per request repeating forever.
What's the real way?

Good luck, creating a Comet app with Java Servlets is a pretty complicated undertaking. Plus Tomcat wasn't really designed for it. I suggest you check out StreamHub Comet Server.

As rajax says, developing a Comet app in servlets is a really bad idea.

Related

Retrieving JSON from an external API with backbone

I'm new to backbone.js and I've read other solutions to similar problems but still can't get my example to work. I have a basic rails api that is returning some JSON from the url below and I am trying to access in through a backbone.js front end. Since they are one different servers I think I need to use a 'jsonp' request. I'm currently doing this by overriding the sync function in my backbone collection.
Api url:
http://guarded-wave-4073.herokuapp.com/api/v1/plans.json
sync: function(method, model, options) {
options.timeout = 10000;
options.dataType = 'jsonp';
options.url = 'http://guarded-wave-4073.herokuapp.com/api/v1/plans.json'
return Backbone.sync(method, model, options);
}
To test this I create a new 'plans' collection in my chrome console using "plans = new Plans()" and then "plans.fetch()" to try and get the JSON.
When I call plans.models afterwards I still have an empty array and the object that returns from plans.fetch() doesn't seem to have any json data included.
Any ideas where I'm going wrong?
I have had the same problem before. You should not have to override your sync method.
Taken from Stackoverflow Answer
"The JSONP technique uses a completely different mechanism for issuing HTTP requests to a server and acting on the response. It requires cooperating code in the client page and on the server. The server must have a URL that responds to HTTP "GET" requests with a block of JSON wrapped in a function call. Thus, you can't just do JSONP transactions to any old server; it must be a server that explicitly provides the functionality."
Are you sure your server abides to the above? Test with another compatible jsonp service (Twitter) to see if you receive results?
Have you tried overriding the fetch method as well?
You should add ?callback=? to your api url in order to enable jsonp

How do I collect data from a website that uses AJAX, with Perl?

This might seem a bit backwards, but I want to use Perl (and Curl if possible) to get data from a site that is using Ajax to fill an HTML shell with information. How do I make these Javascript calls to get the data I need?
The website is here: http://www.jigsaw.com/showContactUpdateTab.xhtml?companyId=224230
Remember that AJAX calls are ordinary HTTP requests, so you always should be able to perform them.
Open Firebug or Web Inspector on the website you're talking about, you'll see some XHR calls:
XHR finished loading: "http://www.jigsaw.com/dwr/interface/UserActionAPI.js".
"http://www.jigsaw.com/dwr/call/plaincall/UserActionAPI.getMostPurchasedContacts.dwr".
"http://www.jigsaw.com/dwr/call/plaincall/UserActionAPI.getRecentlyGraveyardedContacts.dwr
"http://www.jigsaw.com/dwr/call/plaincall/UserActionAPI.getRecentlyAddedContacts.dwr".
"http://www.jigsaw.com/dwr/call/plaincall/UserActionAPI.getRecentlyTitleChangedContacts.dwr"
Yay! Now you know where to get that data. Their scripts use POST HTTP request to the URLs above, so if you open them in your browser, you'll see various engine errors.
When you sniff (via Web Inspector debugger, for example) their AJAX POST requests, you'll see the next body:
"callCount=1
page=/showContactUpdateTab.xhtml?companyId=224230
httpSessionId=F5E7EC4A45DFCE87B969A9F4FA06C361
scriptSessionId=D020EFF4333283B907402687182D03E034
c0-scriptName=UserActionAPI
c0-methodName=getRecentlyGraveyardedContacts
c0-id=0
c0-param0=number:224230
c0-param1=boolean:false
c0-param2=boolean:false
batchId=1
"
I'm pretty sure, they're generating a bunch of security session IDs to avoid data miners. You may need to dive into their JavaScript codes to learn more about those generators.
Some applications have code in place to check that the client is a real AJAX client. They simply the check for the presence of the header X-Requested-With: XMLHttpRequest. So it's easy to circumvent:
curl -H 'X-Requested-With: XMLHttpRequest' ...
use HTTP::Request::Common;
GET $url, 'X-Requested-With' => 'XMLHttpRequest', ...
Of course, you might have to deal with the usual stuff, like required cookies (for the session), nonce parameters, the occasional complexity. Firebug or the like for other browsers will help you reverse-engineer the required headers and parameters.

Cross domain javascript ajax request - status 200 OK but no response

Here is my situation:
Im creating a widget that site admins can embed in their site and the data are stored in my server. So the script basically has to make an ajax request to a php file in my server to update the database. Right? Right :)
The ajax request works excellent when i run it in my local server but it does not work when the php file is on my ONLINE server.
This is the code im using:
var url = "http://www.mydomain.net/ajax_php.php";
var params = "com=ins&id=1&mail=mymail#site.net";
http.async = true;
http.open("POST", url, true);
http.onreadystatechange = function() {
if(http.readyState == 4 && http.status == 200) {
//do my things here
alert( http.responseText );
}
}
http.send(params);
In firebug it shows: http://www.mydomain.net/ajax_php.php 200 OK X 600ms.
When i check the ajax responnseText I always get a Status:0
Now my question is: "Can i do cross-domain ajax requests by default? Might this be a cross-domain ajax problem? Since it works when the requested file resides in my local server but DOESN'T work when the requested file is in another server, im thinking ajax requests to another remote server might be denied? Can you help me clear on this?
Thanks..
Cross-domain requests are not directly allowed. However, there is a commonly-used technique called JSONP that will allow you to avoid this restriction through the use of script tags. Basically, you create a callback function with a known name:
function receiveData(data) {
// ...
}
And then your server wraps JSON data in a function call, like this:
receiveData({"the": "data"});
And you "call" the cross-domain server by adding a script tag to your page. jQuery elegantly wraps all of this up in its ajax function.
Another technique that I've had to use at times is cross-document communication through iframes. You can have one window talk to another, even cross-domain, in a restricted manner through postMessage. Note that only recent browsers have this functionality, so that option is not viable in all cases without resorting to hackery.
You're going to need to have your response sent back to your client via a JSONP call.
What you'll need to do is to have your request for data wrapped in a script tag. Your server will respond with your data wrapped in a function call. By downloading the script as an external resource, your browser will execute the script (just like adding a reference to an external JS file like jQuery) and pass the data to a known JS method. Your JS method will then take the data and do whatever you need to do with it.
Lots of steps involved. Using a library like jQuery provides a lot of support for this.
Hope this helps.

Is there a limit to the number of Ajax requests that can be launched on Apache

Is there a limit to the number of simultaneous Ajax requests than can be launched toward an Apache server? For example, consider the following function to update div elements on a page (prototype JS):
function trigger_content_update(cell) {
//asynchronous : false is required for this to work properly
$$('.update').each(function(update_item){
new Ajax.Request('/neighbouring?.state=update_template&dummy='+(new Date()).getTime(),{
asynchronous: false,
parameters: {divid: update_item.id, source: cell},
onComplete: function(response) {
var elm = response.getHeader('Element');
if ($(elm) !== null) { $(elm).update(response.responseText) }
}
});
});
}
On my HTML page, there are 8 div elements that are marked with the "update" CSS selector, thus launching 8 ajax requests. The code works fine with the asynchronous property set to false, but as soon as i set asynchronous:true i can observe (in Firebug) most Ajax requests returning a 500 status (internal server error).
Once this occurs, it is required to restart apache to recover.
I'd check the server side code that's handling the requests.
As far as Apache is concerned, your Ajax request is just a POST - the same as if you'd submitted a form. 8 simultaneous requests should easily be handled by Apache, so it suggests that the server side code that Apache is running is locking up - perhaps it's trying to write to a data file and finding it locked?
I just wrote a test case where I sent out 10,000 simultanuous Ajax calls to a service. Works fine on Apache Tomcat. All service came back with a proper answer.
It sounds like your service is having some internal synchronization issues.

NETWORK_ERROR: XMLHttpRequest Exception 101

I am getting this Error
NETWORK_ERROR: XMLHttpRequest Exception 101
when trying to get XML content from one site.
Here is my code:
var xmlhttp;
if(window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
}
if (xmlhttp==null) {
alert ("Your browser does not support XMLHTTP!");
return;
}
xmlhttp.onReadyStateChange=function() {
if(xmlhttp.readyState==4) {
var value =xmlhttp.responseXML;
alert(value);
}
}
xmlhttp.open("GET",url,false);
xmlhttp.send();
//alert(xmlhttp.responseXML);
}
xmlhttp.open("GET",url,false);
xmlhttp.send(null);
Does any one have a solution?
If the url you provide is located externally to your server, and the server has not allowed you to send requests, you have permission problems. You cannot access data from another server with a XMLHttpRequest, without the server explicitly allowing you to do so.
Update: Realizing this is now visible as an answer on Google, I tried to find some documentation on this error. That was surprisingly hard.
This article though, has some background info and steps to resolve. Specifically, it mentions this error here:
As long as the server is configured to allow requests from your web application's origin, XMLHttpRequest will work. Otherwise, an INVALID_ACCESS_ERR exception is thrown
An interpretation of INVALID_ACCESS_ERR seems to be what we're looking at here.
To solve this, the server that receives the request, must be configured to allow the origin. This is described in more details at Mozilla.
The restriction that you cannot access data from another server with a XMLHttpRequest can apply even if the url just implies a remote server.
So:
url = "http://www.myserver.com/webpage.html"
may fail,
but:
url = "/webpage.html"
succeed - even if the request is being made from www.myserver.com
Request aborted because it was cached or previously requested? It seems the XMLHttpRequest Exception 101 error can be thrown for several reasons. I've found that it occurs when I send an XMLHttpRequest with the same URL more than one time. (Changing the URL by appending a cache defeating nonsense string to the end of the URL allows the request to be repeated. -- I wasn't intending to repeat the request, but events in the program caused it to happen and resulted in this exception).
Not returning the correct responseText or responseXML in the event of a repeated request is a bug (probably webKit).
When this exception occurred, I did get an onload event with readyState==4 and the request object state=0 and responseText=="" and responseXML==null. This was a cross domain request, which the server permits.
This was on an Android 2.3.5 system which uses webKit/533.1
Anyone have documentation on what the exception is supposed to mean?
Something like this happened with me when I returned incorrect XML (I put an attribute in the root node). In case this helps anyone.
xmlhttp.open("GET",url, true);
set the async part to true
I found a very nice article with 2 diferent solutions.
The first one implementing jQuery and JSONP, explaining how simple it is.
The second approach, it's redirecting trough a PHP call. Very simple and very nice.
http://mayten.com.ar/blog/42-ajax-cross-domain
Another modern method of solving this problem is Cross Origin Ressource Sharing.
HTML5 offers this feature. You can "wrap" your XMLhttp request in this CORS_request and
if the target browser supports this feature, you can use it and wont have no problems.
EDIT:
Additionaly i have to add that there are many reasons which can cause this Issue.
Not only a Cross Domain Restriction but also simply wrong Settings in your WEB.CONFIG of your Webservice.
Example IIS(.NET):
To enable HTTP access from external sources ( in my case a compiled Phonegap app with CORS request ) you have to add this to your WEB.CONFIG
<webServices>
<protocols>
<add name="HttpGet"/>
<add name="HttpPost"/>
</protocols>
</webServices>
Another scenario:
I got two webservices running... One on Port 80 and one on Port 90. This also gave me an XML HTTP Request Error. I even dont know why :). Nevertheless i think this can help many not well experienced readers.

Resources