2

我使用 python 脚本通过 ajax 将文本显示到屏幕上,但它很滞后,有时甚至无法正常工作。

这是python脚本

#!/usr/bin/env python
import cgi, cgitb
form = cgi.FieldStorage()
q = form.getvalue('q')
print "Content-Type: text/html\n" 
print q

和html

<!DOCTYPE html>
<html>
<head>
    <script type="text/javascript">
        function show(str){
            var xmlhttp;
            if (str.length == 0){
                document.getElementById("hint").innerHTML = "";
                return;
            }
            if(window.XMLHttpRequest){
                xmlhttp=new XMLHttpRequest();
            }
            else{
                xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
            }
            xmlhttp.onreadystatechange=function(){
                if (xmlhttp.readyState==4 && xmlhttp.status==200){
                    document.getElementById("hint").innerHTML=xmlhttp.responseText;
                }
            }
            xmlhttp.open("GET","../cgi-bin/ajax_test.py?q="+str,true);
            xmlhttp.send();
        }
    </script>
</head>
<body>
    <form action="">
        <input type="text" id="txt1" onkeyup="show(this.value)" />
    </form>
    <span id="hint"></span>
</body>

是我的代码的错吗?还是因为 cgi/python 很慢?

4

2 回答 2

3

虽然您的示例在本地 OSX apache 服务器上对我来说效果很好,但我建议使用 python CGI 作为后端解决方案来提供 ajax 调用将非常低效。CGI 的本质意味着每个请求都必须生成该 python 脚本的进程。

http://en.wikipedia.org/wiki/Common_Gateway_Interface

调用命令通常意味着调用服务器上新创建的进程。与生成输出的实际工作相比,启动进程可能会消耗更多的时间和内存,尤其是当程序仍需要解释或编译时。如果经常调用该命令,则由此产生的工作负载会很快使 Web 服务器不堪重负。
通过使用编译的 CGI 程序(例如 C/C++ 中的程序)而不是使用 Perl 或其他脚本语言,可以减少解释中涉及的开销。可以通过 FastCGI 等解决方案或使用 mod_php 等扩展模块在 Web 服务器中完全运行应用程序代码来减少进程创建所涉及的开销。

虽然它可能在本地运行得很好,只需要您进行测试,但当您将其设为面向公众并连接多个客户端时,它会受到更大的影响。

wsgi(或至少是 fastcgi)是一种优于老式 CGI 脚本的方法。如果您使用的是 apache,则可以使用 mod_wsgi。我相信还有uwsgigunicorn和许多其他方法。最终的想法是,不是为每个请求调用一个独立的脚本,而是有一个正在运行、接受请求和执行函数的持久进程。

这些天来,我认为人们只是使用 python CGI 模块作为通过 python 编写服务器端 Web 代码的学习步骤。您可能需要考虑迁移到框架。

于 2012-06-04T21:51:52.323 回答
0

当使用 python 作为 cgi 时,对于每个请求,必须启动一个新的 python iterpreter 来处理请求,这自然包括一些进程创建的开销。

当您为每个keyup事件发送新请求时,后台可能会启动很多进程。change捕获事件或者仅在按下返回时发送请求可能会更好。

除此之外,最好使用wsgi而不是 cgi 来运行您的脚本,因为这样可以避免在每个请求上重新启动解释器。

于 2012-06-04T21:56:55.370 回答