以下代码,如果我对run.py进行ajax调用,然后在html标记中显示输出。脚本run.py运行超过2分钟。但是在下面的js脚本中。一旦脚本开始运行。输出(输出的初始行)将显示在html标记中。不会显示脚本的剩余部分。
$(document).ready(function(){
$(sub).click(function(){
alert("connecting to host")
$.ajax({
type:'POST',
url:'/cgi-bin/run.py',
dataType: 'html',
success:function (z) {
$('#output').html(z);
}
});
}) ;
});
我想知道ajax中是否有任何函数要等到脚本完成(不仅仅是执行脚本。而是等到结束)然后将整个输出显示到html标记。
这是我的python脚本:
import sys, os
import cgi, cgitb
def __init__(self, address, username, password):
# connects to host
def sendShell(self, command):
#opens shell
def process(self):
while self.shell.recv_ready():
info += self.shell.recv(1024)
output = str(info, "utf8")
print(output)
hostname = "z.com"
password = "yyy"
username = "dd"
connection = ssh(hostname, username, password)
connection.openShell()
connection.sendShell("date");
答案 0 :(得分:0)
jQuery.ajax()
有一个选项async: false
,不过我会反对它并在ajax回调中做你需要的任何事情。此外,它已被弃用。
答案 1 :(得分:0)
将$ .Ajax函数的async标志更改为false几乎是正确的,但在您的情况下,脚本需要运行很长时间,因此您需要考虑使用长轮询来处理此类请求。
原因是因为浏览器对ajax调用具有最大超时时间,并且通常设置为1分钟,具体取决于浏览器(因此在您的情况下,客户端/浏览器在1分钟后停止连接并希望响应,但您希望它等到它完成然后才发回响应)。 因此,为了克服这个问题,你必须发送一次20秒或一次最大超时的另一个请求到py脚本以检查它是否完成。
javascript端的代码段:
function isDone(timestamp) {
timestamp = timestamp || null;
$.ajax({
type:'POST',
url:'/cgi-bin/run.py',
dataType: 'json',
data: { "timestamp": timestamp },
timeout: 20000, // Or to whatever the max-timeout is, haven't checked that with jQuery.
success: function (response) {
if (response.done === false) {
isDone(Date.now ());
} else {
// got the results, can continue.
$('#output').html(response.output);
}
}
});
}
isDone();
我不确定pyton脚本应该是什么样子,如果你想让你可以与我分享它,我会尝试完成服务器端。 基本上你应该做的是将脚本的超时设置为最大值,并将正确的响应返回给客户端。
JSON响应应如下所示:
{
"done": true, // or false if the script timed out.
"output": html, // the variable that should contain the output when the py script is done, if its not done just send a null or don't send it back to the client at all.
"timestamp": time.time() // if im not wrong that's how you get timestamp in py
}
伪代码中的服务器端:
Dynamcally or under setting, configure python script execution time to max or rather to 3 min, sense you mentioned it takes 2 min.
if (timestamp === null) { // first ajax call to this script.
- Start long processing task.
- Write the output to a file.
}
do { // check this code block every 1 sec
if (the file you are writing to was created and is complete / unlocked) {
- Read from that file the content, save it into a variable and delete the file from your system.
- Output the above mentioned response with done set to true and the current timestamp.
- Break outside of the loop
}
if (timed out) { // basically check if 20 second passed sense starting timestamp.
- Output the above mentioned response with done set to false and the current timestamp.
- Break outside of the loop.
}
sleep for 1 sec, you don't want to kill your CPU usage.
} while (true)