python-3.x 下面的代码段中的user_input = post_data.split('=')[1]是什么?

wlp8pajw  于 8个月前  发布在  Python
关注(0)|答案(2)|浏览(67)

我正在编写一段Python代码来处理来自HTML服务器的POST请求方法。下面的代码块是在回答我之前提出的一个问题时提供给我的。我已经逐行检查了它,以确保我理解了这里的逻辑。但是我在这一行遇到了一个障碍。
第一个月
所以我将概述我认为逻辑是做什么的,然后提供实际的代码,我希望有人能在适当的地方纠正我,以确保我正确理解逻辑。此外,解释为什么上面的代码行存在,我不明白为什么在这种情况下需要split方法。
post_data不能简单地按原样打印出来吗?或者这会因为某种原因导致问题吗?
我在这里提供的顶部部分是上下文,因为它是程序的其余部分。

# Python 3 server example
from  http.server import BaseHTTPRequestHandler, HTTPServer 
import time #Why is time imported if it's not used? Hypothesis: the send response method on line 10 states among other things to send the current date. Thus time is needed to determine current date?

hostName = "localhost"
serverPort = 8080

class MyServer(BaseHTTPRequestHandler): 
    def do_GET(self): 
        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.end_headers()
        self.wfile.write(bytes("<html><head><title>https://pythonbasics.org</title></head>", "utf-8"))
        self.wfile.write(bytes("<p>Request: %s</p>" % self.path, "utf-8"))
        self.wfile.write(bytes("<body>", "utf-8"))
        self.wfile.write(bytes("<p>Hello world! This is a webpage!</p>", "utf-8"))
        self.wfile.write(bytes("<p> And hello to you! Please enter your name below!</p>", "utf-8"))
        self.wfile.write(bytes("""<form action="/" method="post">
                                   <label for="name">Please enter your name:</label><br>
                                   <input type="text" id="name" name="name"><br>
                                   <input type = "submit" value = "Click me!">
                                </form>  
                              """, "utf-8" )) 
        self.wfile.write(bytes())
        self.wfile.write(bytes("</body></html>", "utf-8"))

字符串
下面这一部分是我想验证我对代码的理解的部分。我认为这里逻辑上发生了什么,代码中的注解中包含了一些额外的问题。

def do_POST(self): 
        content_length = int(self.headers['Content-Length']) 
        #The content-string above is an html header responsible for declaring the length of the text being passed to the server via the POST method. 
        #However, Content-Length is never declared a value that I can tell, not here or in the rest of the program. So, does HTML then by default take the entire doccument provided by the POST method if Content-Lengtg is not assigned any value?
        # It is then coerced into an int and passed to the content_length variable. But what is the purpose of the ".headers" method?
       
        post_data = self.rfile.read(content_length).decode('utf-8') 
        #utf-8 is the unicode format for encoding/decoding the given text. .read is being passed the length of the message and thus is reading the entire message. The message is then passed to .rfile, I am not sure why this is, why is the standard .read method not sufficent?
        
        user_input = post_data.split('=')[1] 
        #I really have no idea why this the split method is needed at all. Could post_data not be used as it is?

        self.send_response(200) 
        #Sends the webpage the 200 response code indicating the server proccessed the request correctly.
        self.send_header('Content-type', 'text/html')
        #Declares that the data about to be sent is of the type text, and is written in HTMl
        self.end_headers()

        self.wfile.write(bytes("html>head>title>https://pythonbasics.org</title>/head>", "utf-8"))
        #I don't understand the use of the bytes class in these lines. I'm assuming that html needs information passed to it to be encoded into bytes for the transfer? This class does so?
        self.wfile.write(bytes("<body>", "utf-8"))
        self.wfile.write(bytes(f"<p>Hello {user_input}!</p>", "utf-8"))
        #At the beginning of this string after the bytes class ther is a single "f" present. Why is this? Is it something to do with html coding or python? Also am I right in thinking that {user_input} is the syntax in HTML for inserting a variable?
        self.wfile.write(bytes("</body></html>", "utf-8"))

t5fffqht

t5fffqht1#

作为一名软件开发人员,你要开发的许多东西之一就是尝试事物的能力。可能发生的最糟糕的事情是什么?错误,到处都是错误(如果你得到参考,请用巴斯光年的声音阅读它)。
我们喜欢遇到bug和错误吗?嗯,通常不是......但我们也不总是悲伤。错误是一个学习的机会,可以通过清理代码,创建有用的日志,了解新的软件包功能等来学习。
我的观点是:不要害怕测试。如果你面对别人的代码,你不确定某些东西是做什么的,或者为什么它会在那里,不要害怕删除它并重新编译代码!
例如.
另一个有用的功能是搜索和阅读软件包文档。是的,有时候这很无聊,但在大多数情况下,它会保存你的一天,甚至教你一两个新东西。
例如.
提示:如果你不理解 * 继承 * 的概念,也许你应该后退一步,在深入研究像这个web服务器这样的例子之前,加强一下面向对象编程的概念。
当从一个已经编码的类继承时,查看文档总是一个好主意。我将为您保存几次点击并直接将链接放在这里。
在那里你可以找到关于属性wfile的信息。据说,

wfile

包含用于将响应写回客户端的输出流。在写入此流时必须正确遵守HTTP协议,以便成功实现与HTTP客户端的互操作。

  • 在版本3.6中更改 *:这是一个io.BufferedIOBase流。

文档实际上是将我们重定向到另一个文档,这很好。这种情况经常发生。我们现在需要知道什么是“io.BufferedIOBase流”。或者,更具体地说,我们需要知道它的write方法是做什么的。
文档非常简单,给予我们第一句话的答案:

writeB,/)

写入给定的字节类对象b,并返回写入的字节数(总是等于b的字节长度,因为如果写入失败,将引发OSError)。
这个难题已经解决了。write方法需要一个“类似字节”的对象作为输入,这就是为什么我们在调用self.wfile.write时使用bytes的原因。
这两项技能(测试和阅读文档)是您更好地理解软件开发世界中的工作方式的核心工具。我觉得在回答您的具体问题之前,给予这些背景知识是很重要的。但是现在让我们开始吧

为什么需要split

我也会花一些时间来给予你一些其他主题的概述。我不是Maven,但希望你会觉得这很有趣。
使用HTTP表单时,了解用户传递的信息如何发送到服务器是很有用的。为此,您可以运行服务器代码,通过任何浏览器访问其页面链接,然后打开“devtools”(请查看如何在this link上执行此操作)。最后,打开“Network”选项卡
你会看到它一开始是空的,但随后就测试你的代码:输入你的名字并点击按钮。现在,可能出现了一些请求。
查找POST请求,因为它是按钮单击事件调用的请求。我们怎么知道呢?在您的代码中,<form>标记有以下选项<form action="/" method="post">,它表示服务器在单击按钮时运行POST类型的方法。
选择POST请求后,查找它的头。它有很多头,但现在只有一个有用:“Content-Type”。它说明了用户输入的数据将如何写入请求中。请参阅下面的打印屏幕
x1c 0d1x的数据
application/x-www-form-urlencoded声明我们将以名称-值对的形式写入信息,如name1=value1&name2=value2&name3=value3等(SO上有一些答案谈到了这一点,如this one
这开始敲响警钟,不是吗?但让我们深入一些。您可以在“Payload”选项卡上看到发送到服务器的实际信息。我也为您打印了它



你可以猜到我写了一个X并点击了按钮。但是看,这是浏览器发送的信息。属性的名称是“name”,因为表单的label标签中有一个选项。如果你把它改成类似<label for="banana">的东西,我们就会在浏览器中看到banana=X
这就是浏览器如何将信息发送到服务器。从服务器端,您需要以某种方式读取它。这是通过rfile.read方法实现的。

现在你知道了文档的路径,你会明白这个方法需要一个整数来表示要读取的字节数。令人高兴的是,这个字节数是在请求头中的“Content-Length”键下发送的。
你可以在第一次打印时检查一下,在我的例子中,“Content-Length”是6:属性的名称(name)是4个字节长; =符号是1个字节长;我的答案(X)也是1个字节长。这就是为什么Content-Length是6。
现在你可能已经把一切都弄清楚了:

  • 您需要使用content_length变量来获取POST有效负载的大小(以字节数为单位
  • 当阅读有效负载时,您将获得类似于由=分隔的“名称/值”对的信息
  • 因为你只想打印"Hello {user_answer}",你只需要值,所以你split有效负载name=user_answervoilà

这是一个相当长的解释“为什么”代码是这样写的。我经常享受这种阅读文档的旅程,但它可能会很无聊,我知道。
另一种理解“为什么”的方法是修改你的代码,打印整个post_data,然后你会看到name=answer被打印出来,你可能会自己弄清楚一切。
我希望你已经学到了一两件事。如果你喜欢,可以随意询问更多。祝你编码愉快(:

bxjv4tth

bxjv4tth2#

原因是因为post_data变量包含“name=<the_text_input>“,那么如果你想要文本输入值;你必须拆分字符串并获得最后一部分。

相关问题