在表单提交上获取GET而不是POST

时间:2018-04-24 06:43:38

标签: python forms post get

python代码启动一个Web服务器,它有这些感兴趣的网页:

  1. index.html:这包含一个带有用户名和密码的HTML表单
  2. configure.html:此页面应使用POST用户名&提交index.html表单时的密码
  3. import ubinascii
    import utime
    import socket
    import select
    
    
    html = """<!DOCTYPE html>
    <html>
        <head> <title>Ouroboros IoT Login</title> </head>
        <body>
            <form action="configure.html" method="POST">
                Username : <input type="text"  name="username"></br>
                Password: <input type="password" name="password" ></br>
                    <input type="submit" value="submit" name="submit">
            </form>
        </body>
    </html>
    """
    
    # Find out the post parameters in a dictionary
    def get_post_params(req):
        print("Inside  POST PARAMS : req = " + req)
        post_params = req.split('\r\n')[-1:][0]
        # Check if the post body contains the necessary fields
        # Split the post_params by &
        # params : ['username=', 'password=', 'method=POST', 'url=http%3A%2F%2Ftwig-me.com%2Fv1%2Fusergroups%2FWKMUYXELA9LCC', 'jsondata=', 'submit=submit']
        print("post_params : " + post_params)
        params = post_params.split('&')
        print("Params")
        print(params)
        # Initialize the key value pair dict
        post_dict = {}
        # Iterate on each param
        for param in params:
            # Each param would be like 'method=POST', etc
            key_val = param.split('=')
            print("Key Val :")
            print(key_val)
            key = key_val[0]
            val = key_val[1]
            # Update post_dict
            post_dict[key] = val
        return post_dict
    
    # This web server takes care of the WiFi configuration
    # max_run_sec 
    def web_server(max_run_sec = None):
        # Create server socket
        addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
        s = socket.socket()
        # TODO : If both the wifi and sta are operating simultaneously, then bind only to WiFi
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind(addr)
        s.listen(1)
        poller = select.poll()
        poller.register(s, select.POLLIN)
        startTimeEpoch = utime.time()
    
        while True:
            all_events = poller.poll(200)  # time in milliseconds
            if len(all_events) > 0:
                try:
                    print("Just after GC Collect!")
                    gc.collect()
                    #print("Just before accepting")
                    res = s.accept()
                    client_s = res[0]
                    client_addr = res[1]
                    req = ''
                    req = client_s.recv(4096)
                    req = req.decode()
                    req = str(req)
                    # Came here means that there has been some connection!
                    # Reset the start time epoch in such a case:
                    startTimeEpoch = utime.time()
                    # Check route now
                    if req.find('configure.html') != -1:
                        print("Got configure request!\r\n")
                        # Check if the username and password are correct, if not, configure:
                        login_config = get_login_config()
                        username = login_config['user']
                        pwd = login_config['password']
                        print("Username : " + username + ", pwd : " + pwd)
                        # Find the POST PARAMETERS sent
                        # There would be just one entry in the array, so get the 0th index directly
                        # post_params : 'username=&password=&method=POST&url=http%3A%2F%2Fjam-me.com%2Fv1%2Fusergroups%2FWKMUYXELA9LCC&jsondata=&submit=submit'
                        post_dict = get_post_params(req)
                        # Now check if the post_dict has the key and value for username and password as needed?
                        username_post = post_dict['username']
                        password_post = post_dict['password']
                        # Check if the password is same as expected
                        if (username_post == username) and (password_post == pwd):
                            hidden_input = '<input type="hidden" name="username" value="' + username + '"><input type="hidden" name="passphrase" value="' + pwd + '">'
                            # Send the login username and password inside the hidden input field
                            configure_html = "<!DOCTYPE html><html><head> <title>Ouroboros IoT WiFi Configuration Page</title> </head><body><form action=\"configure_wifi.html\" method=\"POST\">WiFi SSID : <input type=\"text\"  name=\"essid\"></br>WiFi Password: <input type=\"password\" name=\"passphrase\" ></br>" + hidden_input + "<input type=\"submit\" value=\"submit\" name=\"submit\"></form></body></html>"
                            # TODO : Also show link to webpage, where from we can change the login credentials
                            client_s.send(configure_html)   
                        else:
                            client_s.send(login_fail_html)
                    elif req.find('configure_wifi.html') != -1:
                        # Check if the username and password are correct, if not, configure:
                        login_config = get_login_config()
                        username = login_config['user']
                        pwd = login_config['password']
                        # Get post parameters
                        post_dict = get_post_params(req)
                        # Now check if the post_dict has the key and value for username and password as needed?
                        username_post = post_dict['username']
                        password_post = post_dict['password']
    
                        # Check if the password is same as expected
                        if (username_post == username) and (password_post == pwd):
                            # Do some sanity check for handling the new wifi ssid and password
                            new_wifi_ssid = post_dict['essid']
                            new_wifi_passphrase = post_dict['passphrase']
                            # Set the wifi credentials
                            save_wifi_config(new_wifi_ssid, new_wifi_passphrase)
                            client_s.send('<!DOCTYPE html><html><head> <title>Ouroboros IoT WiFi Configuration Success</title> </head><body>Configuration successful!<br>Device would go into reboot now!</body></html>')
                            # Reboot device now
                            machine.reset()
                        else:
                            client_s.send(login_fail_html)
                    elif req.find('index.html') != -1:
                        print("Got index.html request!\r\n")
                        client_s.send(html)
                    else :
                        # Do nothing
                        print("Invalid request received! Show the login page again!\r\n")
                        client_s.send(html)
    
                except OSError:
                    # Got no request and it timedout!
                    print("Timed-out, no request received!\r\n")
                except Exception as e:
                    print("Got some exception\r\n")
                    print(str(e))
                finally:
                    client_s.close()
                    if max_run_sec is not None:
                        elapsedTime = utime.time() - startTimeEpoch
                        if elapsedTime >  max_run_sec:
                            # Max run time of web server has elapsed, time to exit this mode!
                            break
        # Unregister poller
        poller.unregister(s)
        # When while loop ends!
    

    当我访问index.html时,一切正常,网页就会出现。然而。当我在输入admin / admin而不是POST后点击提交时,我在网络服务器上收到一个GET请求,其内容如下:

    Inside POST PARAMS : req = GET /configure.html HTTP/1.1
    Host: 192.168.0.1
    Connection: keep-alive
    Cache-Control: max-age=0
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/65.0.3325.181 Chrome/65.0.3325.181 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
    Accept-Encoding: gzip, deflate
    Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
    

    奇怪的是,我没有通过POST,而是获得了GET。谁能找到明显的错误?我在Ubuntu,ESP8266 micropython上使用Chromium网页浏览器。

1 个答案:

答案 0 :(得分:1)

问题是你的HTML无效,足以让它强迫浏览器猜测我的意思模式&#34;,浏览器显然很混乱,可以猜到错误。< / p>

我无法在macOS,iOS和Android上的各种不同的Chrome,Safari和Firefox浏览器上重现问题 - 他们都正确地发送了POST。但是,无法匹配的标签错误正是可能导致此类问题的一种方式。

特别是,您有两个</br>标记,这些标记是您从未打开的<br>的结束标记。很可能这只是<br />的错字或思考(自我结束标签)。

您可能还有其他错误。在HTML5中,虽然属性名称始终不区分大小写,但并非所有属性值都是。我非常确定HTML 5.2明确要求枚举属性来进行ASCII不区分大小写的匹配,但是IIRC,HTML 5.0没有指定它。如果是这样,并且如果您的浏览器不是最新的,从技术上讲,它可以合法地将POST视为无效值并使用无效值默认值get,而不是将其视为post }。我实际上并不确定这是真的 - 即使是这样,我也无法找到一个实际上就是这样的浏览器,并且无法想象任何人都有充分的理由这样做所以我怀疑这是你的问题。但仍然没有理由不做对。

因此,修复方法是将HTML更改为:

html = """<!DOCTYPE html>
<html>
    <head> <title>Ouroboros IoT Login</title> </head>
    <body>
        <form action="configure.html" method="post">
            Username : <input type="text"  name="username"><br />
            Password: <input type="password" name="password" ><br />
                <input type="submit" value="submit" name="submit">
        </form>
    </body>
</html>
"""

更一般地说,您应该始终使用外部验证器验证您的HTML,或者只使用几乎每个浏览器中内置的开发人员工具。如果您看到HTML错误或警告,请修复它们 - 特别是如果您还看到无法解释的行为,但即使您不是。

相关问题