Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
210 views
in Technique[技术] by (71.8m points)

How do I utilize AJAX within an older Perl/CGI web chat script that currently uses meta tags to refresh and uses outdated HTML frames?

I am currently stuck on a personal project/learning project of mine on my personal server running Linux Fedora. I took an old open-source web chat called Ralf's Chat from sourceforge and I'm trying to modernize it, update and add a few features. It is a Perl/CGI script using MySQL database to store data and it displays chat messages and all other data (settings page, input form and users online list) via HTML frames which I am also trying to do away with and use newer methods. The problem where I am stuck is trying to use AJAX to smoothly load data and send incoming data to the server instead of relying on the annoying and disruptive way it currently uses which is via use of meta http-equiv refresh tags. Unfortunately I am not sure exactly where in this script to do so or the right way to code it as I have yet to use AJAX side of Javascript.

The script currently has the following scripts and their purpose is as follows:

  • Chat.cgi - handles chat/message stuff Chat2.cgi - specifies all the userlevel, session, settings, profile, etc. related stuff Chatpm.cgi
  • Post message script Chatsa.cgi - "Still alive" or users online script. Config.cgi - stores config variables
  • Shared.cgi - contains shared/misc. subroutines

and all the corresponding html pages joined together via HTML frames in html/chatframes.cgi which must go!

Here is the current subroutines that handles posting messages if this will help, this is from shared.cgi

    my $pm_type = $_[0];
    my $pm_from = $_[1];
    my $pm_to = $_[2];
    my $pm_message = $_[3];
    
    if ($pm_message) {
        # checking recipient (if set), checking sender, too, for preventing infinite loop
        if ($pm_to and not &nick_exists($pm_to) and &nick_exists($pm_from)) {
            &postmsg("command", "MSG", $session{'name'}, &msgargs($msg{'unf'}, [$pm_to]));
        } else {
            my $message_id = &gettime.".$$.";
            if ($msgcount++ > 'Y') {
                $msgcount = 'A';
            }
            $message_id .= $msgcount;
            for (my $n=0; $n<2; $n++) { 
            $message_id .= chr(int(rand(26))+65); 
        }

        # kill linebreaks
        $pm_message =~ s/
/ /g;

        my $msg;
        if ($pm_type eq "public") {
        # LOG PUBLIC MSG
        &logfile("[MSG] $session{'name'}: $pm_message", 3);

        # remove old public messages
        if ($use_dbi) {
# <DBI>
            $sth = $dbh->prepare("SELECT message_timestamp FROM $data{'messages'} WHERE type='public' AND room=$session{'room'} ORDER BY message_timestamp DESC");
            $sth->execute;
            my $i = 1;
            while (my $row = $sth->fetchrow_arrayref) {
                $i++;
                if ($i >= $message_limit) {
                    $dbh->do("DELETE FROM $data{'messages'} WHERE message_timestamp<$$row[0] AND room=$session{'room'}");
                    last;
                }
            }
# </DBI>
        } else {
# <NODBI>
            &file_open("messages", ">");
            my @messages = <READFILEMESSAGES>;
            my @messages2;
            my $i = 1;

            while (@messages) {
                my $temp = pop @messages;
                my @temp = split(/;;/, $temp);
                unshift @messages2, $temp if ($i < $message_limit or $temp[6] != $session{'room'});
                $i++ if ($temp[0] eq "public");
            }
            foreach (@messages2) {
                print WRITEFILEMESSAGES;
            }
            &file_close("messages", ">");
# </NODBI>
        }
        
        $pm_message = &wash_msg($pm_message);
        $msg = "<B>$pm_from</B>: $pm_message";
    } elsif ($pm_type eq "private") {
        $pm_message = &wash_msg($pm_message);
        $msg = "<B>[$pm_from]</B> $pm_message";
        &logfile("[PRIVATE] FROM: $pm_from TO: $pm_to: $msg", 3);
    } elsif ($pm_type eq "private_out") {
        $pm_message = &wash_msg($pm_message);
        $msg = "<B>[->$pm_from]</B> $pm_message";
    } elsif ($pm_type eq "action") {
        $msg = "$pm_message";
    } elsif ($pm_type eq "command") {
        $msg = "<B>[$pm_from]</B> $pm_message";
    } elsif ($pm_type eq "memo") {
        $msg = "<B>[$pm_from]</B> $pm_message";
    } elsif ($pm_type eq "me") {
        $pm_message = &wash_msg($pm_message);
        $msg = "<B>*$pm_from $pm_message</B>";
    } elsif ($pm_type eq "plain") {
        $msg = "$pm_message";
    }
        
    if ($pm_type ne "action") {
        if ($query{'selected_action'}) {  
            $msg = "<IMG SRC="$actions{$query{'selected_action'}}" ALIGN=LEFT>$msg";
        }
        if ($posting_time) {
            $msg = "<SPAN CLASS="time">".strftime($posting_time_format, localtime($timestamp))."</SPAN> $msg";
        }
        if ($session{'color'} ne "standard" and $pm_type =~ /^(public|private|private_out|memo|me)$/) {
            $msg = "<FONT COLOR="#$session{'color'}">$msg</FONT>";
        }
    }
    
    # remove old private messages
    if ($pm_to) {
        if ($use_dbi) {
# <DBI>
            $sth = $dbh->prepare("SELECT message_timestamp FROM $data{'messages'} WHERE message_to='$pm_to' ORDER BY message_timestamp DESC");
            $sth->execute;
            my $i = 1;
            while (my $row = $sth->fetchrow_arrayref) {
                $i++;
                if ($i >= $message_limit) {
                    $dbh->do("DELETE FROM $data{'messages'} WHERE message_timestamp<$$row[0] AND message_to='$pm_to'");
                    last;
                }
            }
# </DBI>
        } else {
# <NODBI>
            &file_open("messages", ">");
            my @messages = <READFILEMESSAGES>;
            my @messages2;
            my $i = 1;
            while (@messages) {
                my $temp = pop @messages;
                my @temp = split(/;;/, $temp);
                unshift @messages2, $temp if ($i < $message_limit or !$temp[2]);
                $i++ if (lc($temp[2]) eq lc($_[2]));
            }
            foreach (@messages2) {
                print WRITEFILEMESSAGES;
            }
            &file_close("messages", ">");
# </NODBI>
        }
    }

    if ($use_dbi) {
# <DBI>
        $msg =~ s/'/&#39;/g;
        $sth = $dbh->do("INSERT INTO $data{'messages'} VALUES ('$pm_type', '$pm_from', '$pm_to', '$msg', $timestamp, '$message_id', $session{'room'})"); 
# </DBI>
    } else {
# <NODBI>
        &file_open("messages", "a");
        print APPENDFILEMESSAGES "$pm_type;;$pm_from;;$pm_to;;$msg;;$timestamp;;$message_id;;$session{'room'}
";
        &file_close("messages", "a");
# </NODBI>
        }
    }
    }
}

sub wash_msg { # $_[0] msg to 'wash'
    &quote($_[0]);

    # link urls
    # *://* (eg. http or ftp
    $_[0] =~ s/(w*://[^ "]+)/<A HREF="$scriptgu_name?$1" TARGET="_blank">$1</A>/g;
    
    # mailto:*
    $_[0] =~ s/(mailto:.+)/<A HREF="$1">$1</A>/g;
    
    # Bad Word Filter
    foreach (@bad_words) {
    $_[0] =~ s/Q$_E/$filter/gi;
    }

    # Smileys / Replace
    while ((my $key, my $value) = each %replace) {
    &kill_special_chars($key);
    &kill_special_chars($value);
    $_[0] =~ s/Q$keyE/$value/g;
    }

    return $_[0];
}

sub kill_special_chars {
    # kill ;
    $_[0] =~ s/;/&#59;/g;
    # kill '
    $_[0] =~ s/'/&#39;/g;
    # kill 
    $_[0] =~ s/\/&#92;/g;
}

sub quote { # quote special characters
    &kill_special_chars($_[0]);
    # kill html-tags
    $_[0] =~ s/</&lt;/g;
    $_[0] =~ s/>/&gt;/g;
    $_[0] =~ s/"/&quot;/g;

    # kill linebreaks
    $_[0] =~ s/(
|
|
)/<BR>/g;
    
    # kill trailing ;
    $_[0] =~ s/;$/; /g;
}

sub unquote { # unquote special characters
    $_[0] =~ s/<BR>/
/g;
}

The part in is for using the optional flat-file mode which I am not, I'm using the DBI.

Here is the current chatframes.cgi which displays all script output and needs to use something other than frames

sub chatframes_html {
    print << "[END]";
<HTML>
<HEAD>
<TITLE>$html_title</TITLE>
</HEAD>
[END]

    if ($banner_url) {
    print << "[END]";
<FRAMESET ROWS="65,*,60" BORDER=0 FRAMEBORDER=0 FRAMESPACING=0>
 <FRAME SRC="$banner_url" SCROLLING=NO>
[END]

    } else {
        print << "[END]";
<FRAMESET ROWS="*,60" BORDER=0 FRAMEBORDER=0 FRAMESPACING=0>
[END]

    }
    print << "[END]";
 <FRAMESET COLS="*,150" BORDER=0 FRAMEBORDER=0 FRAMESPACING=0>
[END]

    if ($session{'streaming'}) {
    print << "[END]";
  <FRAME NAME="main" SRC="$scriptst_name?action=stream&id=$query{'id'}&pause=$pause">
[END]

    } else {
    print << "[END]";
  <FRAME NAME="main" SRC="$script_name?action=chat&id=$query{'id'}&pause=$pause#end">
[END]

    }
    if ($room) {
    print << "[END]";
  <FRAMESET ROWS="*,70" BORDER=0 FRAMEBORDER=0 FRAMESPACING=0>
   <FRAME SRC="$scriptsa_name?action=stillalive&id=$query{'id'}">
   <FRAME SRC="$script2_name?action=rooms&id=$query{'id'}" SCROLLING=NO>
  </FRAMESET>
[END]

    } else {
    print << "[END]";
  <FRAME SRC="$scriptsa_name?action=stillalive&id=$query{'id'}">
[END]

    }
    print << "[END]";
 </FRAMESET>
 <FRAME SRC="$scriptpm_name?action=chatinput_html&id=$query{'id'}" scrolling=no>
</FRAMESET>
</HTML>
[END]

}

1;

# EOF

Any help would be greatly appreciated. Thank you.

question from:https://stackoverflow.com/questions/65858503/how-do-i-utilize-ajax-within-an-older-perl-cgi-web-chat-script-that-currently-us

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...