【问题标题】:Keeping a variable around from post to get?保持一个变量从发布到获取?
【发布时间】:2010-09-26 09:10:38
【问题描述】:

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

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

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

我想让 get() 方法知道我在 post() 中得到的变量的值。这是这里的重点。

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

有没有办法以某种方式访问​​“发布实例”?

有解决办法吗?如果必须,是否有一种既定的方法可以将值从 post 发送到“new.html”并与 get-submit 一起发回?

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

【问题讨论】:

    标签: python google-app-engine post get


    【解决方案1】:

    我不具体了解谷歌应用引擎,但通常情况如下:

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

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

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

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

    另一种解决方案是将项目作为您从第一个函数生成的 HTML 中的 url 参数发送回页面,然后您将“照常”从第二个函数中获取这些项目。

    【讨论】:

    • Web 会话通常不是用户独有的——单个用户可以同时拥有多个会话,并且 Web 服务器通常不知道用户是谁(Web 应用程序会处理)。跨度>
    • 用户不是这里的实体。它是一个抽象概念,由以某种方式存储并在通信过程中传递的特殊 id 表示。从技术上讲,“用户”可以被多个应用程序同时克隆和使用,或者一个应用程序可以有多个。
    【解决方案2】:

    这不是如何管理实例的问题。因为 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 参数应该用于有副作用的指令,即修改数据。恕我直言,应避免将参数从 POST 移动到 get。
    2. 如果我们需要持久性,使用对象实例(或我的示例中的函数范围)通常不是一个好主意。
      1. 如果是具有较低保留需求的非敏感信息cookies 是要走的路。它们是客户端的一种持久性机制,因此您可以从请求中获取它们,除非您更改它们,否则它们将被保留(当然直到到期)。
      2. 如果您需要更多地控制保留,您应该使用本地持久性机制。服务器缓存(任何类型的)、文件系统、数据库......当然,您需要手动过滤每个用户。

    无论如何我都会避免在实例上缓存。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

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

          有几种方法可以解决这个问题,所有这些方法都依赖于首先记​​住您正在参加会议的技术。

          HTTP 没有提供任何帮助。您必须在服务器上找到保存会话状态的地方,并在客户端上找到记录会话标识的地方。两大技术是

          • 使用 cookie 来识别会话。无缝且无声。

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

          • 在有限的情况下,您还可以在表单中使用隐藏字段。这仅在您在每个页面上都有表单时才有效。并非总是如此。

          这是它在实践中的表现。

          1. 获取响应。检查标头中的 cookie。

            一个。没有饼干。初次使用者。创建会话。将其保存在某处(内存、文件、数据库)。将唯一 ID 放入 cookie。知道这是他们第一次回复。

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

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

            • 德拉特。没有会话。老饼干。创建一个新的并表现得像这是他们的第一次访问。

          2. POST 响应。检查标头中的 cookie。

            一个。没有饼干。怎么回事?傻孩子。离开我的草坪!有人在 POST 上添加了书签或试图弄乱你的脑袋。像第一次 GET 一样响应。

            b.曲奇饼。优秀。得到饼干。

            • 找到会话对象。在会话对象中找到你需要的东西。回复。

            • 德拉特。没有会话。老饼干。创建一个新的并像第一次 GET 一样响应。

          您可以使用查询字符串而不是 cookie 来做同样的事情。或表单上的隐藏字段。

          【讨论】:

            【解决方案6】:

            好的——谢谢大家。

            我会尽快尝试其中的一些想法,然后回复大家。

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

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

            【讨论】:

            • 没有足够的信息来评论“不良做法”
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2021-11-24
            • 2013-10-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-12-05
            • 2015-02-16
            相关资源
            最近更新 更多