python - refrescar - implementar ajax en django
¿Cómo implementar un servidor mínimo para AJAX en Python? (4)
Aquí hay un ejemplo simple para Python 3 basado en el ejemplo de @ nikow
Sé que esto puede tener errores, comenta cuáles son si los encuentras.
El código envía la cadena "Te envié este mensaje" cuando haces clic en ejecutar, Python responde con "Lo tengo"
Código HTML
(Vas a tener que usar la consola js para esto)
<body>
<button id="runButton">Run</button>
<script type="text/javascript">
function xml_http_post(url, data) {
var req = new XMLHttpRequest();
req.open("POST", url, true);
req.onreadystatechange = function() {
if (req.readyState == 4) {
console.log(req.responseText);
}
}
req.send(data);
}
function runbuttonfunc() {
xml_http_post("frontend.html", "I sent you this message")
}
document.getElementById("runButton").onclick = runbuttonfunc;
</script>
</body>
Código de Python: importe http.server
FILE = ''frontend.html''
PORT = 8000
class TestHandler(http.server.SimpleHTTPRequestHandler):
"""The test example handler."""
def do_POST(self):
"""Handle a post request by returning the square of the number."""
print(self.headers)
length = int(self.headers.get_all(''content-length'')[0])
print(self.headers.get_all(''content-length''))
data_string = self.rfile.read(length)
print(data_string)
self.send_response(200)
self.send_header("Content-type", "text/plain")
self.end_headers()
self.flush_headers()
self.wfile.write("I got it!".encode())
def start_server():
"""Start the server."""
server_address = ("", PORT)
server = http.server.HTTPServer(server_address, TestHandler)
server.serve_forever()
start_server()
Quiero crear una GUI basada en HTML / AJAX muy simple para un programa de Python. Entonces, la interfaz es una página HTML que se comunica con el programa a través de AJAX. ¿Me puede dar una implementación mínima para el lado del servidor utilizando el Python SimpleHTTPServer.SimpleHTTPRequestHandler
?
Un ejemplo simple sería un campo de texto y un botón. Cuando se presiona el botón, el contenido del campo se envía al servidor, que luego envía una respuesta correspondiente. Soy consciente de que hay muchas soluciones potentes para esto en Python, pero me gustaría mantener esto muy simple. Ya encontré algunos buenos ejemplos para un servidor de este tipo (por ejemplo, here ), pero hasta ahora no podía encontrar uno realmente mínimo.
En caso de que se pregunte por qué deseo implementar la GUI de esta manera: mi enfoque para esta aplicación es mostrar muchos datos en un diseño agradable con una interacción mínima, por lo que el uso de HTML + CSS parece más conveniente (y ya he estado usándolo para visualización de datos no interactiva).
Gracias por un ejemplo muy intuitivo. @nikow. Intenté seguir tu ejemplo, pero obtuve un error:
(proceso: 10281): GLib-CRITICAL **: g_slice_set_config: assertion ''sys_page_size == 0'' failed
Modifiqué tu código para satisfacer mis necesidades.
webbrowser.open(''file:///home/jon/workspace/webpages/frontend_example/%s'' % FILE)
// skipped the port part
httpd = make_server("", 8080, test_app)
// hardcoded it here.
¿Mi archivo html debe ser puesto en el servidor web? ¡No lo he puesto todavía!
OK, creo que ahora puedo responder mi propia pregunta. Aquí hay una implementación de ejemplo para calcular el cuadrado de un número en el servidor. Por favor, avíseme si hay mejoras o conceptos erróneos.
el archivo del servidor python:
import threading
import webbrowser
import BaseHTTPServer
import SimpleHTTPServer
FILE = ''frontend.html''
PORT = 8080
class TestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
"""The test example handler."""
def do_POST(self):
"""Handle a post request by returning the square of the number."""
length = int(self.headers.getheader(''content-length''))
data_string = self.rfile.read(length)
try:
result = int(data_string) ** 2
except:
result = ''error''
self.wfile.write(result)
def open_browser():
"""Start a browser after waiting for half a second."""
def _open_browser():
webbrowser.open(''http://localhost:%s/%s'' % (PORT, FILE))
thread = threading.Timer(0.5, _open_browser)
thread.start()
def start_server():
"""Start the server."""
server_address = ("", PORT)
server = BaseHTTPServer.HTTPServer(server_address, TestHandler)
server.serve_forever()
if __name__ == "__main__":
open_browser()
start_server()
... y el archivo HTML (lo llamo ''frontend.html'', desafortunadamente el nombre debe aparecer en el código JavaScript también):
<html>
<head>
<title>AJAX test</title>
</head>
<body>
<script type="text/javascript">
function xml_http_post(url, data, callback) {
var req = false;
try {
// Firefox, Opera 8.0+, Safari
req = new XMLHttpRequest();
}
catch (e) {
// Internet Explorer
try {
req = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e) {
try {
req = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e) {
alert("Your browser does not support AJAX!");
return false;
}
}
}
req.open("POST", url, true);
req.onreadystatechange = function() {
if (req.readyState == 4) {
callback(req);
}
}
req.send(data);
}
function test_button() {
var data = document.test_form.test_text.value;
xml_http_post("frontend.html", data, test_handle)
}
function test_handle(req) {
var elem = document.getElementById(''test_result'')
elem.innerHTML = req.responseText
}
</script>
<form name=test_form>
sqr(
<input type="text" name="test_text" value="0" size="4">
) =
<span id="test_result">0</span>
<input type=button onClick="test_button();" value="start" title="start">
</form>
</body>
</html>
Por supuesto, sería mucho más conveniente usar jQuery para la solicitud XML, pero en aras de la simplicidad lo dejo así.
Finalmente, una implementación alternativa usando WSGI (desafortunadamente no vi una manera de recurrir al controlador estándar de publicación de archivos si la solicitud no es un POST):
import threading
import webbrowser
from wsgiref.simple_server import make_server
FILE = ''frontend.html''
PORT = 8080
def test_app(environ, start_response):
if environ[''REQUEST_METHOD''] == ''POST'':
try:
request_body_size = int(environ[''CONTENT_LENGTH''])
request_body = environ[''wsgi.input''].read(request_body_size)
except (TypeError, ValueError):
request_body = "0"
try:
response_body = str(int(request_body) ** 2)
except:
response_body = "error"
status = ''200 OK''
headers = [(''Content-type'', ''text/plain'')]
start_response(status, headers)
return [response_body]
else:
response_body = open(FILE).read()
status = ''200 OK''
headers = [(''Content-type'', ''text/html''),
(''Content-Length'', str(len(response_body)))]
start_response(status, headers)
return [response_body]
def open_browser():
"""Start a browser after waiting for half a second."""
def _open_browser():
webbrowser.open(''http://localhost:%s/%s'' % (PORT, FILE))
thread = threading.Timer(0.5, _open_browser)
thread.start()
def start_server():
"""Start the server."""
httpd = make_server("", PORT, test_app)
httpd.serve_forever()
if __name__ == "__main__":
open_browser()
start_server()
Use la implementación de referencia de WSGI . A la larga, serás más feliz.
from wsgiref.simple_server import make_server, demo_app
httpd = make_server('''', 8000, demo_app)
print "Serving HTTP on port 8000..."
# Respond to requests until process is killed
httpd.serve_forever()
La demo_app es relativamente fácil de escribir; maneja sus solicitudes de Ajax.