好的,我设法让它工作,我想要(虽然有些/最可能不同意的方法).我使用了Flask,如下所示.可能被认为“错误”的部分是404检查循环.这不是正确的设计,并导致一些浏览器中的“卡住脚本”错误,如果它持续了很长时间.但是,我想运行的脚本不会持续足够长的时间,这是一个问题.
感谢您的帮助,如果您有任何其他建议,请通知我.
Flask应用程序:
import threading import subprocess import os import sys from flask import Flask from flask import render_template,abort app = Flask(__name__) app.debug = True def run_script(): theproc = subprocess.Popen([sys.executable,"run_me.py"]) theproc.communicate() @app.route('/') def index(): return render_template('index.html') @app.route('/generate') def generate(): threading.Thread(target=lambda: run_script()).start() return render_template('processing.html') @app.route('/is_done') def is_done(): hfile = "templates\\itworked.html" if os.path.isfile(hfile): return render_template('itworked.html') else: abort(404) if __name__ == "__main__": app.run()
processing.html:
<!DOCTYPE html> <html> <head> <script src="/static/jquery.min.js"></script> </head> <body> <p>Processing...</p> <script> setInterval(function() { var http = new XMLHttpRequest(); http.open('HEAD',"is_done",false); http.send(); if (http.status==200) window.location.replace("is_done"); },2000); </script> </body> </html>
原来的问题:
我是初学者/中级Python程序员和开始的Web开发人员,所以请温柔.
我想要的是:
用户点击一个超链接,并被带到一个描述类似“处理…”的中间网页.在后台(在服务器上),此链接触发一个python脚本来处理文件并创建一个新的网页.完成脚本后,用户被重定向到新创建的页面.
我拥有的:
我有一个脚本来处理和吐出一个新的页面.我没有想到的是如何触发python脚本,然后在脚本完成时触发重定向.我看过像django和cgi脚本这样的web框架.但我没有发现任何我觉得适合账单的东西.这是非常可能的,我只是错过了一些完全明显的东西,所以我真的很感激任何帮助.
谢谢.
解决方法
解决这个问题的一个简单方法是使用简单的Web框架,如Flask来构建您的系统的Web部件.在您的魔术链接的请求处理程序中,您需要生成脚本并跟踪它.一个简单的方法来查看您的脚本是否完成并将其传递给您的用户是定期发送一个ajax请求以检查完成.
所以例如Flask网站可能看起来像:
import threading import subprocess import uuid from flask import Flask from flask import render_template,url_for,abort,jsonify,request app = Flask(__name__) background_scripts = {} def run_script(id): subprocess.call(["/path/to/yourscript.py","argument1","argument2"]) background_scripts[id] = True @app.route('/') def index(): return render_template('index.html') @app.route('/generate') def generate(): id = str(uuid.uuid4()) background_scripts[id] = False threading.Thread(target=lambda: run_script(id)).start() return render_template('processing.html',id=id) @app.route('/is_done') def is_done(): id = request.args.get('id',None) if id not in background_scripts: abort(404) return jsonify(done=background_scripts[id])
和index.html:
<a href="{{ url_for('generate') }}">click me</a>
和processing.html:
<html> <head> <script src="/static/jquery.js"></script> <script> function ajaxCallback(data) { if (data.done) window.location.replace("http://YOUR_GENERATED_PAGE_URL"); else window.setTimeout(function() { $.getJSON('{{ url_for('is_done') }}',{id: {{ id }} },ajaxCallback); },3000); } $(document).ready(function(){ ajaxCallback({done=false}); }); </script> </head> <body> Processing... </body></html>
这是目前所有未经测试的代码,但我希望您能够了解如何解决此问题.还要记住,只有在从一个进程中提供页面时,这才有效,所以如果您设置Apache和mod_wsgi,请确保进程组中只有一个进程.
如果您需要更复杂的解决方案,您可能需要查看消息队列等.