CGI Python脚本 - 加法游戏

时间:2014-09-17 21:08:15

标签: python cgi

对于一个类,我必须创建一个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!"

1 个答案:

答案 0 :(得分:1)

您缺少HTTP的基本请求 - 响应特性。您不能在单个CGI请求中多次要求用户输入,您只能在开始时输入一个输入,然后返回一个输出。

处理这个问题的传统方法是打破代码,这样每个输出都是一个带有表单的网页,它可以使用下一个输入再次调用CGI脚本(或调用另一个脚本)状态(如您的answercounttotal)存储在隐藏的表格变量或Cookie中。

现代的方法是编写一个在浏览器中运行的AJAX应用程序,使用JavaScript代码跟踪状态并发出“Web服务”请求,然后适当地修改页面的DOM,而不是下载整个新的一页。但是值得学习如何首先采用CGI方式。


Python维基上的

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以来,已经很长一段时间了,有了不带引号的属性和未封闭的标签之类......)