jquery.js在Perl模板工具包生成的文件中没有正确引用

jquery.js not referencing properly within Perl Template Toolkit-generated files

本文关键字:文件 引用 Perl js 工具包 jquery      更新时间:2023-09-26

我有一个非常简单的JavaScript/Perl CGI示例,我用它来开始一个更大的项目。当我以client.htmlserver.pl的身份运行它时,它可以完美地工作。但是,当我将client.html更改为client.tmpl,并使用模板工具包从相同的server.pl脚本调用它时,它似乎找不到jQuery函数。

我甚至创建了一个master.tmpl文件,并在其中使用[% INCLUDE client.html %],它失败了。浏览器控制台验证jquery.js的路径是正确的,但是当它在模板中时,它就像无法加载它一样。

下面是HTML文件,我基本上试图变成一个.tmpl文件(格式混乱,第一次在这里,抱歉):

client.html

<!DOCTYPE html>
<html>
    <head>
        <title>AJAX Example</title>
        <meta charset="UTF-8" />
        <script src="http://domainname/ajax_example/jquery.js"></script>
        <script type="text/javascript">
        function myTimer() {
            var typingTimer;
            var doneTypingInterval = 2000;
            $("#user_text").keyup( function() {
               clearTimeout(typingTimer);
               if ( $('#user_text' ).val()) {
                   typingTimer = setTimeout(updateText, doneTypingInterval);
               }
            });
            function updateText() {
                var current_text = document.getElementById('user_text').value;
                var http = new XMLHttpRequest();
                http.onreadystatechange = function() {
                    if ( http.readyState == 4 && http.status == 200 ) {
                        var response = http.responseText;
                        document.getElementById('server_response').value = response;
                    }
                };
                http.open("GET", "http://domainname/ajax_example/cgi-bin/server.pl?user_text=" + current_text , true );
                http.send();
            }
        }
        </script>
    </head>
    <body>
        <div>Input Text: <input type="text" id="user_text" name="user_text"  onkeyup="myTimer()"/></div><br/>
        <div>Server Resp.: <textarea id="server_response"  name="server_response"> </textarea></div>
        <br/>
    </body>
</html>

有效的server.pl:

server.pl

$cgi = CGI->new;
$id = $cgi->param('user_text');
$result = uc($id);
print $cgi->header();
print $result;

不工作的server.pl:

server.pl

$cgi = CGI->new;
$id = $cgi->param('user_text');
**returned from result calculation sub** $result = uc($id);
my $config = {
    EVAL_PERL    => 1,
    POST_CHOMP   => 1,
    INTERPOLATE => 1,
    INCLUDE_PATH => '/usr/lib/cgi-bin/ajax_example/:/var/www/html/ajax_example/',  
};
    print $cgi->header( -charset=>'utf-8' );
    my $tt = Template->new($config);
    $tt->process('client.tmpl', '$result);
}

请记住,我正在尽最大努力总结代码,但是Perl和JavaScript工作得很好,除非它是通过TT使用的。错误是:

#user_text.keyup is not a function:
("#user_text").keyup(function(){

同样的错误,我会得到,如果我把一个坏的路径到jquery.js。毫无疑问,这条路很好。

谢谢大家的推荐

直接的问题是您启用了INTERPOLATE选项,该选项会在模板中的任何地方插入Perl变量。这使得模块尝试用它的值替换$(,并破坏JavaScript语法

无论如何,这是一种使用模板的草率方式:你应该在$vars散列中传递你需要的所有值,并使用[% variable %]模板指令从那里提取它们。这同样适用于EVAL_PERL选项,因为任何复杂的数据操作通常都应该在调用process的代码中。你需要在模板内做的所有事情都可以通过template指令

获得。

说到$vars哈希,你应该得到Not a HASH reference错误,因为你传递给process的是对字符串变量$result的引用,而不是包含该值的哈希。目前还不清楚如何处理该值,但是在HTML中唯一提到的id是HTML底部的<input>元素的id属性,因此我在它们中放置了一个指令来向您展示它是如何工作的

看一下这段代码

CGI程序

use strict;
use warnings 'all';
use CGI;
use Template;
my $cgi    = CGI->new;
my $id     = $cgi->param('user_text') // 'abc123';
my $result = uc $id;
print $cgi->header( -charset => 'utf-8' );
my $tt = Template->new( {
    # INCLUDE_PATH => '/usr/lib/cgi-bin/ajax_example/:/var/www/html/ajax_example/', 
    POST_CHOMP   => 1,
} );
$tt->process('client.html', { result => $result } );

我已经像这样修改了你的HTML文件。我不知道你想用CGI代码从user_text参数中提取的值做什么,所以我把它放在value属性中作为第一个输入字段

模板文件

<!DOCTYPE html>
<html>
    <head>
        <title>AJAX Example</title>
        <meta charset="UTF-8" />
        <script src="http://domainname/ajax_example/jquery.js" />
        <script type="text/javascript">
            function myTimer() {
                var typingTimer;
                var doneTypingInterval = 2000;
                $("#user_text").keyup( function() {
                   clearTimeout(typingTimer);
                   if ( $('#user_text' ).val() ) {
                       typingTimer = setTimeout(updateText, doneTypingInterval);
                   }
                } );
                function updateText() {
                    var current_text = document.getElementById('user_text').value;
                    var http = new XMLHttpRequest();
                    http.onreadystatechange = function() {
                        if ( http.readyState == 4 && http.status == 200 ) {
                            var response = http.responseText;
                            document.getElementById('server_response').value = response;
                        }
                    };
                    http.open("GET",
                        "http://domainname/ajax_example/cgi-bin/server.pl?user_text=" + current_text,
                        true );
                    http.send();
                }
            }
        </script>
    </head>
    <body>
        <div>Input Text:
            <input type="text" id="user_text" name="user_text" value="[% result %]" onkeyup="myTimer()"/>
        </div>
        <br/>
        <div>Server Resp.:
            <textarea id="server_response"  name="server_response"/>
        </div>
        <br/>
    </body>
</html>

下面是CGI代码的输出结果。如您所见,$("#user_text").keyup调用保持不变,并且来自CGI代码的值(在$vars散列中传递的result元素)已被替换为文本input元素

value属性

我希望这能帮助你进步,让你的应用程序工作

输出
Content-Type: text/html; charset=utf-8
<!DOCTYPE html>
<html>
    <head>
        <title>AJAX Example</title>
        <meta charset="UTF-8" />
        <script src="http://domainname/ajax_example/jquery.js" />
        <script type="text/javascript">
            function myTimer() {
                var typingTimer;
                var doneTypingInterval = 2000;
                $("#user_text").keyup( function() {
                   clearTimeout(typingTimer);
                   if ( $('#user_text' ).val() ) {
                       typingTimer = setTimeout(updateText, doneTypingInterval);
                   }
                } );
                function updateText() {
                    var current_text = document.getElementById('user_text').value;
                    var http = new XMLHttpRequest();
                    http.onreadystatechange = function() {
                        if ( http.readyState == 4 && http.status == 200 ) {
                            var response = http.responseText;
                            document.getElementById('server_response').value = response;
                        }
                    };
                    http.open("GET",
                        "http://domainname/ajax_example/cgi-bin/server.pl?user_text=" + current_text,
                        true );
                    http.send();
                }
            }
        </script>
    </head>
    <body>
        <div>Input Text:
            <input type="text" id="user_text" name="user_text" value="ABC123" onkeyup="myTimer()"/>
        </div>
        <br/>
        <div>Server Resp.:
            <textarea id="server_response"  name="server_response"/>
        </div>
        <br/>
    </body>
</html>