programing

Python에서 AJAX용 최소 서버를 구현하는 방법은 무엇입니까?

showcode 2023. 4. 5. 22:28
반응형

Python에서 AJAX용 최소 서버를 구현하는 방법은 무엇입니까?

Python 프로그램용 매우 심플한 HTML/AJAX 기반의 GUI를 만들고 싶습니다.따라서 프런트엔드는 AJAX를 통해 프로그램과 통신하는 HTML 페이지입니다.python을 사용하여 서버 측에 최소한의 구현을 제공할 수 있습니까?SimpleHTTPServer.SimpleHTTPRequestHandler?

간단한 예로는 텍스트 필드와 버튼을 들 수 있습니다.버튼을 누르면 필드의 내용이 서버로 전송되고 서버는 해당 응답을 반환합니다.Python에는 많은 강력한 솔루션이 있다는 것을 알고 있습니다만, 매우 심플하게 하고 싶습니다.이러한 서버의 좋은 예(예를 들면, 여기)는 이미 몇개인가 발견했지만, 아직까지는 실제로 최소한의 것을 생각해 낼 수 없었습니다.

GUI를 왜 그렇게 구현하고 싶은지 궁금할 때: 이 어플리케이션의 초점은 많은 데이터를 최소한의 인터랙션만으로 멋진 레이아웃으로 표시하는 것입니다.그래서 HTML+CSS를 사용하는 것이 가장 편리할 것 같습니다(또한 저는 이미 인터랙티브하지 않은 데이터 표시에 사용하고 있습니다).

좋아, 이제 내 질문에 대답할 수 있을 것 같아.서버상의 숫자의 제곱을 계산하기 위한 구현 예를 다음에 나타냅니다.개선사항이나 오해가 있으면 알려주세요.

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()

...HTML 파일('프런트 엔드'라고 부릅니다).html'은 불행히도 자바스크립트 코드에도 이름이 표시되어야 합니다.)

<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>

물론 XML 요청에 jQuery를 사용하는 것이 훨씬 편리하겠지만 단순성을 위해 그대로 두겠습니다.

마지막으로 WSGI를 사용한 대체 구현(요구가 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()

WSGI 참조 구현을 사용합니다.결국, 당신은 더 행복해질 거예요.

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()

demo_app은 비교적 쓰기 쉬우며 Ajax 요청을 처리합니다.

다음은 @nikow의 예를 기반으로 한 Python 3의 간단한 예입니다.

오류가 있을 수 있다는 걸 알고 있습니다. 발견되면 코멘트해 주세요.

run을 클릭하면 코드는 문자열 "I send you this message"를 보냅니다.python은 "I got it"로 응답합니다.

HTML 코드

(이 경우 js 콘솔을 사용해야 합니다.)

<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>

Python 코드:

import 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()

매우 직관적인 예를 들어주셔서 감사합니다.@nikow 님의 예를 따르려고 했는데 오류가 발생했습니다.

(프로세스: 10281): GLIB-CRITIAL **: g_set_config: 어설션 'sys_page_size == 0'이 실패했습니다.

내 필요에 맞게 코드를 수정했습니다.

webbrowser.open('file:///home/jon/workspace/webpages/frontend_example/%s' % FILE)
// skipped the port part
httpd = make_server("", 8080, test_app)
// hardcoded it here.

내 html 파일이 웹서버에 저장되어야 하나요? 아직 거기에 저장하지 않았어요!

언급URL : https://stackoverflow.com/questions/336866/how-to-implement-a-minimal-server-for-ajax-in-python

반응형