【发布时间】:2022-11-10 02:12:40
【问题描述】:
我正在尝试创建一个简单的 Micropython 项目,当微控制器第一次打开时,如果连接到 wifi 不成功,它将开始托管一个接入点。当连接到接入点时,设备会提供一个简单的网页,允许用户输入他们的 SSID 和密码,然后将其存储到设备中以供将来使用。
但是,在提交表单后检索用户在网页中键入的值时,我遇到了问题。这是我的代码:
import ujson as json
import usocket as socket
import network
import time
max_wifi_retry = 30
class ConnectWifi:
# Constructor retrieves stored credentials and saves them to class variables
def __init__(self, credentialsFile='config.json'):
with open(credentialsFile) as fp:
config = json.load(fp)
self.ssid = config["ssid"]
self.password = config["password"]
self.access_point_ssid = config["access_point_ssid"]
# This method will attempt to connect device to wifi
def connectWifi(self):
self.wifi = network.WLAN(network.STA_IF)
#Restarting WiFi
self.wifi.active(False)
time.sleep(0.5)
self.wifi.active(True)
self.wifi.connect(self.ssid, self.password)
if not self.wifi.isconnected():
print('connecting')
wifi_retry_attempts = 0
while not self.wifi.isconnected() and wifi_retry_attempts < max_wifi_retry:
print(max_wifi_retry - wifi_retry_attempts)
wifi_retry_attempts += 1
time.sleep_ms(1000)
if not self.wifi.isconnected():
self.wifi.active(False)
return self.wifi.isconnected()
# This is where I am having trouble knowing what to do
def enableAccessPoint(self):
print('Unable to connect to wifi, enabling wireless access point config')
ap = network.WLAN(network.AP_IF)
ap.active(True)
ap.config(essid=self.access_point_ssid, authmode=network.AUTH_OPEN)
print(ap.ifconfig())
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 80))
s.listen(5)
while True:
try:
conn, addr = s.accept()
print('Got a connection from %s' % str(addr))
request = conn.recv(1024)
print('Content = %s' % str(request))
response = self.getWebPage()
conn.send(response)
conn.close()
except KeyboardInterrupt:
print("break")
break
def getWebPage(self):
html = """
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h1>Configure Wifi</h1>
<form action="/submit" method="post">
<label for="ssid">SSID:</label><br>
<input name="SSID" type="text" id="ssid" value=""><br><br>
<label for="password">Password:</label><br>
<input name="PASSWORD" type="text" id="password" value=""><br><br>
<input type="submit" value="Submit">
</form>
</body>
</html>
"""
return html
简而言之,为了快速解释这个问题,我创建了这个套接字并监听请求:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 80))
s.listen(5)
while True:
try:
conn, addr = s.accept()
print('Got a connection from %s' % str(addr))
request = conn.recv(1024)
print('Content = %s' % str(request))
response = self.getWebPage()
conn.send(response)
conn.close()
except KeyboardInterrupt:
print("break")
break
我试图弄清楚如何修改上面的代码以识别用户请求的页面,并在用户提交表单时读取任何表单参数,这可能吗?
这是供参考的 HTML 表单。
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h1>Configure Wifi</h1>
<form action="/submit" method="post">
<label for="ssid">SSID:</label><br>
<input name="SSID" type="text" id="ssid" value=""><br><br>
<label for="password">Password:</label><br>
<input name="PASSWORD" type="text" id="password" value=""><br><br>
<input type="submit" value="Submit">
</form>
</body>
</html>
【问题讨论】:
-
当你打印出
request = conn.recv(1024)返回的值时,你看到了什么?您确定该请求将适合 1024 字节吗?你了解HTTP request 的样子吗? -
This 可能感兴趣。
-
@larsks 返回的值如下所示: b'GET /submit?SSID=Djxjdk&PASSWORD=Fjdjd HTTP/1.1\r\nHost: 192.168.4.1\r\nUpgrade-Insecure-Requests: 1\r\nAccept: text/html,应用程序/xhtml+xml,应用程序/xml;q=0.9,/;q=0.8\r\nUser-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1\r\n接受-Language: en-US,en;q=0.9\r\nAccept-Encoding: gzip, deflate\r\nConnection: keep-alive\r\n\r\n' 我确实将其更改为 GET 方法而不是POST,所以我可以看到请求中的值!
-
@larsks现在的问题是我正在使用正则表达式来尝试解析输入,这真的很难看。我知道在 micropython 中可能有更好的方法来解决这个问题,但我不确定该怎么做。非常感谢您的意见,非常感谢!
-
http.server 模块不是使用 socket 模块来创建套接字连接,而是定义了用于实现 HTTP 服务器的类,并使编写 Web 服务器应用程序更容易。它不适用于生产级的实施,但对您的应用来说已经足够了。
标签: python esp8266 micropython