检查用户名可用性 - 处理 AJAX 请求(Google App Engine)

Checking username availability - Handling of AJAX requests (Google App Engine)

我想使用 AJAX 在我的注册页面上添加 'check username available' 功能。我对我应该如何实施它没有任何疑问。

  1. 我应该在哪个事件中注册我的 AJAX 请求?我们可以发送 当用户焦点离开 'username' 输入字段时请求(模糊 事件)或他键入时(键盘事件)。哪个提供更好的用户 经验?

  2. 在服务器端,处理请求的一种简单方法是 查询我的主要 'Accounts' 数据库。但这可能会导致很多 请求命中我的数据库(如果我们 POST 使用 keyup 则更多 事件)。我应该为注册用户名维护一个单独的模型吗 只有并使用它来获得更好的结果?

  3. 这种情况下可以使用Memcache吗?初始化缓存 每个用户名作为密钥并在我们注册用户并使用 用于检查缓存是否实际初始化或传递的随机密钥 直接查询 db.

我会推荐用户名字段的模糊事件,结合某种内联 error/warning 显示。

我还建议维护一个注册用户名的内存缓存,以减少数据库命中并改善用户体验 - 虽然可能不会通过预热填充它,而是仅在发出请求时填充它。这有时称为 "Repository" 模式。

但是,您只能使用使用过的用户名填充缓存 - 您不应在此处存储 "available" 用户名(或者如果这样做,请使用更短的超时时间)。

在实际执行注册时,您应该始终直接检查 DB/Datastore。理想情况下,采用某种交易方法,这样您就不会遇到多人注册的竞争条件。

但是,所有这些工作都取决于几个因素,包括您的应用的繁忙程度以及您使用的数据存储技术!

答案-

  1. 检查模糊。如果您在键入时执行此操作,您将用不必要的查询重击您的服务器,烦扰尚未完成输入的用户,并且可能会延迟输入。
  2. 如果您的帐户实体非常大,您可能希望创建一个单独的 AccountName 实体,并在您创建真实帐户时创建一个匹配的此类实体(但这可能是不必要的优化)。当您创建帐户(或帐户名称)时,请务必在创建时分配 id=name。然后你可以做一个AccountName.get_by_id(name)快速查看AccountName是否已经分配,​​如果最近处理过它会自动从memcache中拉取它。
  3. 默认情况下,GAE NDB 会在您放置或获取实体时自动为您填充内存缓存。如果您在第 2 步中遵循我的建议,事情将会非常快,您将不必为预填充内存缓存而烦恼。

如果您担心 2 个人同时请求相同的用户名,请将您的创建方法放在一个事务中:

@classmethod
@ndb.transactional()
def create_account(cls, name, other_params):
    acct = Account.get_by_id(name)
    if not acct:
        acct = Account(id=name, other param assigns)
        acct.put()