对于一个类,我必须创建一个CGI Python脚本,允许用户三次尝试输入他们对一个处理数字从-50到50的附加游戏的答案。如果用户得到的答案不正确3次in程序应该在总计数器中添加一行,并给用户一个新问题。如果用户问题正确,程序应该向总计和正确的计数器添加一个,并给用户一个新问题。
我有一些问题,这是我在网页上的脚本:
http://silo.cs.indiana.edu:14544/cgi-bin/0917/dgerman
以下是代码:
#!/usr/bin/python
import random, cgi, cgitb
cgitb.enable()
print "Content-type: text/html\n\n",
data = cgi.FieldStorage()
(count, total, correct) = (0, 0, 0)
n1 = random.randrange(-50, 50)
n2 = random.randrange(-50, 50)
answer = n1 + n2
if data.keys():
number = data.getvalue('number')
if data.number == answer:
message = "You are correct!"
total += 1
correct += 1
else:
message = "Nope, please try again."
count += 1
total += 1
else:
message = "Welcome."
print """
%s <p>
<form>
What is %s + %s? Answer: <input type=text name=number>
<input type=submit name=action value = Proceed><br>
You have %s out of %s correct!
</form>
""" % (message, n1, n2, correct, total)
print "You have ", 3-count, " tries left!"
答案 0 :(得分:1)
您缺少HTTP的基本请求 - 响应特性。您不能在单个CGI请求中多次要求用户输入,您只能在开始时输入一个输入,然后返回一个输出。
处理这个问题的传统方法是打破代码,这样每个输出都是一个带有表单的网页,它可以使用下一个输入再次调用CGI脚本(或调用另一个脚本)状态(如您的answer
,count
和total
)存储在隐藏的表格变量或Cookie中。
现代的方法是编写一个在浏览器中运行的AJAX应用程序,使用JavaScript代码跟踪状态并发出“Web服务”请求,然后适当地修改页面的DOM,而不是下载整个新的一页。但是值得学习如何首先采用CGI方式。
CgiScripts有一个很好的简单例子。首次访问该页面时,您没有从表单中发送message
,因此会显示Previous message: <no message>
,并为您提供一个表单,用于输入submit
你回到同一页面。您提交的内容,现在 发送了message
,因此会显示Previous message: My message that I typed
,然后会为您提供相同的表单。
所以,将其翻译成您的问题:
第一次访问该页面时,不会选择随机数,到目前为止还没有进行猜测,也不会有新的猜测,因此您的代码将打印{{1} } 信息。到现在为止还挺好。但是您包含的表单还需要(隐藏或可见)字段,这些字段将发回答案,猜测等,以便您可以在下一个请求中将它们从Welcome
中拉出来。
完成后,当您提交时,现在 发送所有这些内容,因此您的代码将显示“正确”或“禁止”消息。对于“nope”情况,您需要再次将所有正确的内容放入表单中以进行下一次猜测。对于“正确”的情况,您将拥有不同的字段 - 或者可能是具有不同值的相同字段(例如,如果您设置FieldStorage
,并且您的通用代码将count = 0
置于表单中,您将在下一个请求的count
中返回0
如果您担心这会让用户通过浏览器中的“查看源代码”轻易欺骗......那么,你是对的。您可以尝试使用未发送给客户端的密钥加密隐藏值,但可以破解。通常的解决方案是找到一些方法来存储服务器端的信息,但没有任何本地状态。例如,您可以创建一个数据库。当有人第一次连接时,您创建会话ID,并将其存储在cookie中。现在,他们发出的每个请求,您都可以使用其cookie中的ID在数据库中查找内容以从上一个请求恢复状态,然后在返回下一个表单之前存储更新的状态。
那么,你如何做隐藏的表单字段?
在现有代码中,您有一个输入字段FieldStorage
。这显示为一个开始为空的文本框,允许用户键入他们想要的任何内容,并且在提交表单时,将文本框的内容作为表单变量<input type=text name=number>
发送,这就是您的number
可以检索它。
如果您想使用值预先填充它,则需要添加data.getvalue('number')
属性。
如果您希望它不是可见或可编辑字段,请使用value='%s'
代替type='hidden'
。然后,无论你在表格中留下什么价值,都会完全按原样发回给你。
因此,例如,如果要在页面加载之间保留type='text'
值,请将其添加到HTML中:
correct
当然,您使用<input type=hidden name=correct value='%s'>
的当前值填写%s
。
然后,您执行correct
而不是仅仅执行correct = 0
。所以,除了第一个请求之外的所有请求,不是从0开始,而是从最后一次开始correct = int(data.getvalue('correct', '0'))
的值。
(我可能已经弄错了一些细节,因为自从我写了老式的HTML 3以来,已经很长一段时间了,有了不带引号的属性和未封闭的标签之类......)