Responding to AJAX - XMLHttpRequest

Hi all,

Perhaps someone experienced with XMLHttpRequest & ruby might be able to
help me. I don't know if it's my ruby code that is failing to properly
respond, or the javascript making the request and handling the response.
I've tried just prototype, just extjs, and as you can see, a mixin of
both as I try and figure out why I only get one response in return. The
only way I can get all of the results found in the search (server
script), is to build a really long string with results and pass just the
one "combined" result. I don't have any more hair to pull out.

tonyd

searchlog.rb

···

---------------------

#!/usr/local/bin/ruby -w
require 'cgi'

@cgi = CGI.new

# Our search params passed from our HTML page
sstring = @cgi['search']
slogtype = @cgi['logtype']
smethod = @cgi['method']

# A hash of possible logs
logs = {'smtp' => 'smtp', 'mail' => 'mails', 'mx' => 'mx', 'spam' =>
'spam', 'Dial Up' => 'radius', 'DHCP' => 'dhcp' }

# Send Response
def send_response(wts)
  @cgi.header { "Content-Type: text/html" } # Not sure if this is
correct - Content? necessary?
  @cgi.out{ "#{wts}" }
end

...
...
# Search through the log
File.open("/var/log/#{logs[slogtype]}",
'r').grep(/#{search_string}/).each do |line|
  # This works but is not "live"..
  response = response << "#{line}<br>" # append to response string

  # This dosen't work - The end result is I only get one response back
at my javascript call
  send_response( "#{line}<br>" ) # send response for each result
end

send_response( response ) # This in conjunction with building of
response string

...
...

searchlog.js
----------------
// Extjs JS Lib - extjs.com
Ext.onReady(function(){

  // Disable the ENTER key from submitting the form
  Ext.get('getinfo').on({
  submit:function(e){
    e.preventDefault();
    return false;
    }
  });

  // Handle form submission
  Ext.get('submitButton').on('click', function(){
        var pars = Form.serialize('getinfo');
        var url = '/cgi-bin/search.rb'
    ajaxUpdate(pars, url);
  });

});

function ajaxUpdate(pars, url) { //Prototype.js function
var ajax = new Ajax.Updater({success: 'results-div', failure:
'results-div'}, url, {
   method: 'get',
   parameters: pars,
   encoding: 'UTF-8',
   insertion: Insertion.Bottom,
});
}
--
Posted via http://www.ruby-forum.com/.

One thing to note is that it is expecting a Content-Type of
application/json as well as the content to be in actual JSON format.
You can simply require 'json' and call wts.to_json which should be
sufficient for your needs.

You might consider looking at Rack for building your tiny web app and
just proxy some address to it; it really cleans up handling requests
and not needing CGI, but your solution does work fine and avoids a
problem with AJAX requests failing due to cross-server requests (which
is what requests not on port 80 are considered).

Matt Todd

···

On Fri, Apr 4, 2008 at 2:54 AM, Tony De <tonydema@gmail.com> wrote:

Hi all,

Perhaps someone experienced with XMLHttpRequest & ruby might be able to
help me. I don't know if it's my ruby code that is failing to properly
respond, or the javascript making the request and handling the response.
I've tried just prototype, just extjs, and as you can see, a mixin of
both as I try and figure out why I only get one response in return. The
only way I can get all of the results found in the search (server
script), is to build a really long string with results and pass just the
one "combined" result. I don't have any more hair to pull out.

tonyd

searchlog.rb
---------------------

#!/usr/local/bin/ruby -w
require 'cgi'

@cgi = CGI.new

# Our search params passed from our HTML page
sstring = @cgi['search']
slogtype = @cgi['logtype']
smethod = @cgi['method']

# A hash of possible logs
logs = {'smtp' => 'smtp', 'mail' => 'mails', 'mx' => 'mx', 'spam' =>
'spam', 'Dial Up' => 'radius', 'DHCP' => 'dhcp' }

# Send Response
def send_response(wts)
  @cgi.header { "Content-Type: text/html" } # Not sure if this is
correct - Content? necessary?
  @cgi.out{ "#{wts}" }
end

...
...
# Search through the log
File.open("/var/log/#{logs[slogtype]}",
'r').grep(/#{search_string}/).each do |line|
  # This works but is not "live"..
  response = response << "#{line}<br>" # append to response string

  # This dosen't work - The end result is I only get one response back
at my javascript call
  send_response( "#{line}<br>" ) # send response for each result
end

send_response( response ) # This in conjunction with building of
response string

...
...

searchlog.js
----------------
// Extjs JS Lib - extjs.com
Ext.onReady(function(){

  // Disable the ENTER key from submitting the form
  Ext.get('getinfo').on({
  submit:function(e){
    e.preventDefault();
    return false;
    }
  });

  // Handle form submission
  Ext.get('submitButton').on('click', function(){
        var pars = Form.serialize('getinfo');
        var url = '/cgi-bin/search.rb'
    ajaxUpdate(pars, url);
  });

});

function ajaxUpdate(pars, url) { //Prototype.js function
  var ajax = new Ajax.Updater({success: 'results-div', failure:
'results-div'}, url, {
   method: 'get',
   parameters: pars,
   encoding: 'UTF-8',
   insertion: Insertion.Bottom,
  });
}
--
Posted via http://www.ruby-forum.com/\.

Matt Todd wrote:

One thing to note is that it is expecting a Content-Type of
application/json as well as the content to be in actual JSON format.
You can simply require 'json' and call wts.to_json which should be
sufficient for your needs.

You might consider looking at Rack for building your tiny web app and
just proxy some address to it; it really cleans up handling requests
and not needing CGI, but your solution does work fine and avoids a
problem with AJAX requests failing due to cross-server requests (which
is what requests not on port 80 are considered).

Matt Todd

Hey Matt,

Thanks for the awesome quick reply. I'll dig into that. That's the
first I heard of this from any blog or forum. But there's some sense to
what you say. I've got to get ruby_json on my freebsd server. I'll let
you know how it goes. Thanks!

tonyd

···

--
Posted via http://www.ruby-forum.com/\.

Tony De wrote:

Matt Todd wrote:

One thing to note is that it is expecting a Content-Type of
application/json as well as the content to be in actual JSON format.
You can simply require 'json' and call wts.to_json which should be
sufficient for your needs.

You might consider looking at Rack for building your tiny web app and
just proxy some address to it; it really cleans up handling requests
and not needing CGI, but your solution does work fine and avoids a
problem with AJAX requests failing due to cross-server requests (which
is what requests not on port 80 are considered).

Matt Todd

Hey Matt,

Thanks for the awesome quick reply. I'll dig into that. That's the
first I heard of this from any blog or forum. But there's some sense to
what you say. I've got to get ruby_json on my freebsd server. I'll let
you know how it goes. Thanks!

tonyd

Ok, got json installed. Making some changes, I still get just the one
reponse. It is, however, passing additional data...
Before: ..data..
Now: "...data..."\n

Firebug Header info: (Maybe useful for you to help me troubleshoot)

Response Headers
Date Fri, 04 Apr 2008 07:46:24 GMT
Server Apache/2.2.0 (FreeBSD) mod_ssl/2.2.0 OpenSSL/0.9.7e-p1 DAV/2
mod_perl/2.0.2 Perl/v5.8.8
Content-Length 159
Keep-Alive timeout=5, max=100
Connection Keep-Alive
Content-Type text/html

Request Headers
Host www.myserver.net
User-Agent Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.12)
Gecko/20080201 Firefox/2.0.0.12
Accept text/javascript, text/html, application/xml, text/xml, */*
Accept-Language en-us
Accept-Encoding gzip,deflate
Accept-Charset ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive 300
Connection keep-alive
X-Requested-With XMLHttpRequest
X-Prototype-Version 1.6.0.2
Referer myserver.net
Authorization Basic dGVjaDp0M2No

searchlog.rb

···

---------------------
#!/usr/local/bin/ruby -w
require 'rubygems'
require 'json'
require 'cgi'

@cgi = CGI.new

# Our search params passed from our HTML page
sstring = @cgi['search']
slogtype = @cgi['logtype']
smethod = @cgi['method']

# A hash of possible logs
logs = {'smtp' => 'smtp', 'mail' => 'mails', 'mx' => 'mx', 'spam' =>
'spam', 'Dial Up' => 'radius', 'DHCP' => 'dhcp' }

# Send Response
def send_response(wts)
  @cgi.out{ wts.to_json }
end

...
...
# Search through the log
@cgi.header { "Content-Type: application/json" } # Send only the one
header back (made no diff to include with each response)
File.open("/var/log/#{logs[slogtype]}",
'r').grep(/#{search_string}/).each do |line|
  send_response( "#{line}<br>" ) # send response for each result
end
--
Posted via http://www.ruby-forum.com/\.