javascript 嵌入python_如何从JavaScript调用python脚本?

匿名用户

您的Python服务器需要做两件事:提供AJAX javascript文件本身(通过GET)

响应来自web客户端的呼叫(通过POST)。

此外,它应该是线程化的,以支持多个同时连接。下面是一个示例,演示如何使用内置的BaseHttpServer完成上述所有工作。

JS(放在static/hello.html中通过Python提供服务):

Hello.

var xhr = new XMLHttpRequest();

xhr.open("POST", "/postman", true);

xhr.setRequestHeader('Content-Type', 'application/json');

xhr.send(JSON.stringify({

value: 'value'

}));

xhr.onload = function() {

console.log("HELLO")

console.log(this.responseText);

var data = JSON.parse(this.responseText);

console.log(data);

}

Python服务器(用于测试):import time, threading, socket, SocketServer, BaseHTTPServer

import os, traceback, sys, json

log_lock = threading.Lock()

log_next_thread_id = 0

# Local log functiondef

def Log(module, msg):

with log_lock:

thread = threading.current_thread().__name__

msg = "%s %s: %s" % (module, thread, msg)

sys.stderr.write(msg + '\n')

def Log_Traceback():

t = traceback.format_exc().strip('\n').split('\n')

if ', in ' in t[-3]:

t[-3] = t[-3].replace(', in','\n***\n*** In') + '(...):'

t[-2] += '\n***'

err = '\n*** '.join(t[-3:]).replace('"','').replace(' File ', '')

err = err.replace(', line',':')

Log("Traceback", '\n'.join(t[:-3]) + '\n\n\n***\n*** ' + err + '\n***\n\n')

os._exit(4)

def Set_Thread_Label(s):

global log_next_thread_id

with log_lock:

threading.current_thread().__name__ = "%d%s" \

% (log_next_thread_id, s)

log_next_thread_id += 1

class Handler(BaseHTTPServer.BaseHTTPRequestHandler):

def do_GET(self):

Set_Thread_Label(self.path + "[get]")

try:

Log("HTTP", "PATH='%s'" % self.path)

with open('static' + self.path) as f:

data = f.read()

Log("Static", "DATA='%s'" % data)

self.send_response(200)

self.send_header("Content-type", "text/html")

self.end_headers()

self.wfile.write(data)

except:

Log_Traceback()

def do_POST(self):

Set_Thread_Label(self.path + "[post]")

try:

length = int(self.headers.getheader('content-length'))

req = self.rfile.read(length)

Log("HTTP", "PATH='%s'" % self.path)

Log("URL", "request data = %s" % req)

req = json.loads(req)

response = {'req': req}

response = json.dumps(response)

Log("URL", "response data = %s" % response)

self.send_response(200)

self.send_header("Content-type", "application/json")

self.send_header("content-length", str(len(response)))

self.end_headers()

self.wfile.write(response)

except:

Log_Traceback()

# Create ONE socket.

addr = ('', 8000)

sock = socket.socket (socket.AF_INET, socket.SOCK_STREAM)

sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

sock.bind(addr)

sock.listen(5)

# Launch 10 listener threads.

class Thread(threading.Thread):

def __init__(self, i):

threading.Thread.__init__(self)

self.i = i

self.daemon = True

self.start()

def run(self):

httpd = BaseHTTPServer.HTTPServer(addr, Handler, False)

# Prevent the HTTP server from re-binding every handler.

# https://stackoverflow.com/questions/46210672/

httpd.socket = sock

httpd.server_bind = self.server_close = lambda self: None

httpd.serve_forever()

[Thread(i) for i in range(10)]

time.sleep(9e9)

控制台日志(chrome):HELLO

hello.html:14 {"req": {"value": "value"}}

hello.html:16

{req: {…}}

req

:

{value: "value"}

__proto__

:

Object

控制台日志(firefox):GET

http://XXXXX:8000/hello.html [HTTP/1.0 200 OK 0ms]

POST

XHR

http://XXXXX:8000/postman [HTTP/1.0 200 OK 0ms]

HELLO hello.html:13:3

{"req": {"value": "value"}} hello.html:14:3

Object { req: Object }

控制台日志(边缘):HTML1300: Navigation occurred.

hello.html

HTML1527: DOCTYPE expected. Consider adding a valid HTML5 doctype: "".

hello.html (1,1)

Current window: XXXXX/hello.html

HELLO

hello.html (13,3)

{"req": {"value": "value"}}

hello.html (14,3)

[object Object]

hello.html (16,3)

{

[functions]: ,

__proto__: { },

req: {

[functions]: ,

__proto__: { },

value: "value"

}

}

Python日志:HTTP 8/postman[post]: PATH='/postman'

URL 8/postman[post]: request data = {"value":"value"}

URL 8/postman[post]: response data = {"req": {"value": "value"}}

此外,您还可以通过在将套接字传递给BaseHttpServer之前包装它来轻松添加SSL。

你可能感兴趣的:(javascript,嵌入python)