保持一个变量从post到get?

时间:2008-12-11 03:50:03

标签: python google-app-engine post get

我有一个名为myClass的类,它定义了post()和get()方法。

index.html ,我有一个表单,其中包含一个调用myClass.post()的操作,该操作从数据库中获取一些数据,设置几个变量并将用户发送到 new.html

现在, new.html 有一个调用myClass.get()的表单。

我希望get()方法知道我在post()中得到的变量的值。这是主要的一点。

我认为来自new.html的提交创建了一个由index.html提交创建的myClass的单​​独实例。

有办法以某种方式访问​​“帖子实例”吗?

有解决方法吗?如果必须,有没有一种既定的方法将邮件中的值发送到“new.html”并通过get-submit发回?

更一般地说,我想我不了解网络编程时我的实例的生命。在正常的交互式环境中,我知道实例何时被创建和销毁,但是当我仅通过调用其方法来使用该类时,我不知道。这些类是否被实例化,除非他们的方法被调用?

6 个答案:

答案 0 :(得分:3)

你所说的是建立一个“会话”。也就是说,一种记住用户和交易状态的方法。

有几种方法可以解决这个问题,所有这些方法都依赖于记忆您首先处于会话中的技术。

HTTP为您提供帮助。您必须找到一些在服务器上保存会话状态的地方,以及在客户端上记录会话标识的地方。

这两大技术
  • 使用Cookie识别会话。无缝而沉默。

  • 使用URL中的查询字符串来标识会话。很明显,因为您的网址中有?sessionid=SomeSessionGUID。这暴露了很多,使书签很烦人。会话清理完毕后,您仍会在人们的书签中隐藏此会话ID。

  • 在有限的方式中,您还可以使用表单中的隐藏字段。这仅适用于每页上都有表单的情况。并非总是如此。

以下是它在实践中的表现。

  1. 获得回应。检查标题中的cookie。

    一个。没有cookie。第一次用户。创建会话。将它保存在某处(内存,文件,数据库)。将唯一ID放入cookie中。回答知道这是他们第一次。

    湾曲奇饼。最近来过这里。尝试获取cookie。

    • 找到会话对象。使用cookie中的信息进行回复。

    • 讨厌鬼。没有会话。老饼干。创建一个新的,这是他们的第一次访问。

  2. POST回复。检查标题中的cookie。

    一个。没有cookie。 WTF?愚蠢的孩子。离开我的草坪!有人给POST添加了书签,或者试图弄乱你的头脑。回应好像是第一次GET。

    湾曲奇饼。优秀。获取cookie。

    • 找到会话对象。在会话对象中找到您需要的东西。作出响应

    • 讨厌鬼。没有会话。老饼干。创建一个新的并回复,好像是第一次GET。

  3. 您可以使用查询字符串而不是Cookie执行相同的操作。或者表单上的隐藏字段。

答案 1 :(得分:1)

这不是如何管理实例的问题。因为HTTP是无状态的,所以你的程序实际上也是无状态的。 (对于长时间运行的过程,比如GAE,它可能会成功,但我不确定你是否需要这种复杂性)

您还没有提供任何代码,但我假设您获得了POST,然后您redirect获得了结果(这是一个GET)。因此,保留参数应该很容易:

def save_foo(request):
    if request.method == 'POST':
        save(request.POST)
        return HttpRedirect(reverse(
            'Some_Target',
            {'bar': 'baz', 'foo': request.POST['foo']}))
    else:
        # do something else

如果是POST,此视图会让客户端向任何别名Some_Target的URL发出GET请求。此GET将包含来自POST的foo参数。

此解决方案适用于单一视图。如果您需要在项目方面采用此行为,则可以使用中间件。而这次缓存变量是有道理的。

有两件事让我对这种方法感到有点不舒服:

  1. 混合GET和POST参数。 GET参数应该用于没有副作用的指令,比如过滤。 POST参数应该用于带有副作用的insructions,即修改数据。应该避免将参数从POST移动到get。
  2. 如果我们需要持久性,使用对象实例(或我的示例中的函数范围)通常不是一个好主意。
    1. 如果是非敏感信息,保留需求较低cookies是可行的方法。它们是客户端持久性的一种机制,因此您可以从请求中获取它们,除非您更改它们,否则它们将被保留(直到有效期为止。)
    2. 如果您需要更多地控制保留,则应使用本地持久性机制。服务器缓存(任何类型),文件系统,数据库......当然,您需要手动过滤每个用户。
  3. 在任何情况下,我都会避免在实例上进行缓存。

答案 2 :(得分:1)

HTTP是无状态的,因此您没有(内置)方式知道加载一个页面的用户是否是加载另一个页面的用户。此外,即使您确实知道,例如,由于会话cookie,您无法确定他们正在加载后续页面的浏览器窗口是否与他们加载前一页面的浏览器窗口相同。用户可以拥有多个标签页访问您的网站,您不希望一个页面的状态更改为另一个页面的更改。

考虑到这一点,您最好的选择是在使用GET提取的页面的链接中包含查询参数,将要发送的变量编码到“获取”页面(确保它们不敏感,因为用户可以修改它们!)。然后你可以通过get.request.GET在get请求中访问它们。

答案 3 :(得分:0)

我不是特别了解谷歌应用引擎,但通常情况下,会发生以下情况:

服务器会有某种线程池。每次向服务器发送http请求时,都会从池中选择一个线程或创建一个线程。

在该线程中,将创建某种控制器对象的实例。此对象将决定如何处理请求(如实例化其他类和预处理http请求参数)。通常,此对象是Web框架的核心。每次浏览器都会重新发送请求参数(服务器无法猜出浏览器想要的内容)。

Web服务器通常具有处于永久或会话状态的对象的状态存储。会话由唯一用户(通常通过URL中的cookie或GUID)表示,该用户在一段时间后过期。

现在,在您的情况下,您需要获取从第一个函数获得的值,将其存储在会话存储区和第二个函数中,从会话存储区中获取这些值。

另一个解决方案是将项目作为第一个函数生成的HTML中的url参数发送回页面,然后你可以从第二个函数中“照常”返回。

答案 4 :(得分:0)

为什么不使用memcache临时存储变量,然后重定向到POST URL?这似乎是最简单的解决方案。

答案 5 :(得分:0)

好的 - 谢谢大家。

我很快就会尝试其中的一些想法,然后再回复你们。

似乎我可以通过从数据存储区*进行大量编写和阅读来解决这些问题,但我认为可能有一种更简单的方法来保持该类的实例(我正在尝试使用我的Web框架中的已知技术,我还没有完全得到)。

*例如,根据POST中的数据创建一个唯一记录,并让一些变量“标记”。这是一种不好的做法吗?