从静态javascript提升会话有效的ajax回调

时间:2012-11-17 10:56:21

标签: javascript ajax lift

我目前正在使用服务器端的lift和d3(一个javascript可视化框架)实现所有可视化的图形可视化工具。我遇到的问题是在脚本中我想从服务器获取与会话相关的数据。

所以基本上,我的目标是在静态js脚本中编写lift-valid ajax回调。

到目前为止我尝试了什么

如果您认为最佳解决方案是我已经尝试过的,请随时发布详细的答案,告诉我如何准确使用它以及它如何完全解决我的问题。

使用lift在另一个脚本中编写ajax回调,并从主脚本

中调用它

此解决方案类似于隐藏文本输入,可能更有可能工作。然而它并不优雅,这意味着我将不得不在加载时加载大量脚本,这不是很方便。

这似乎是电梯社区中首选的解决方案之一,如this discussion on the mailing list.

中所述

REST界面

通常,如果要从javascript函数中获取数据,那么创建REST接口。但是,此接口不会链接到任何会话。这是我从上一个问题得到的解决方案:Get json data in d3 from lift snippet

将函数作为脚本的参数

另一个解决方案是将ajaxcallback作为主脚本的参数来调用以生成我的图形。但是我希望有很多回调,我不想弄乱我的脚本的参数。

将整个脚本写入电梯,然后将其提供给客户端

这个解决方案可以很优雅,但是我的脚本很长,我真的更喜欢它仍然是静态的。

我想要什么

在客户端

在查看我的网页的源代码时,我发现ajaxSelect的回调是:

<select onchange="liftAjax.lift_ajaxHandler('F966066257023LYKF4=' + encodeURIComponent(this.value), null, null, null)" name="F96606625703QXTSWU" id="node_delete" class="input">

此外,还有一个变量包含网页末尾的页面状态:

var lift_page = "F96606625700QRXLDO";

所以,我想知道是否可以使用此liftAjax.lift_ajaxHandler函数模拟我的ajaxcall是有效的。但是我不知道要使用的确切合成器。

在服务器端

由于我在客户端“伪造”了一个请求,我现在想在客户端获取请求并将其发送到正确的函数。这是LiftRules.dispatch对象似乎是最佳解决方案的地方:调用它时,所有会话管理都已完成(请求已经过身份验证并链接到会话),但我不知道如何编写正确的append函数中的一段代码。

备注

在提升中,所有变量名称都被更改为随机字符串以增加安全性,我希望在我的应用程序中具有相同的行为,即使这可能意味着我将不得不“给”这些javascript这些值。但是,15个字符串值的数组仍然是比15个函数更好的权衡,作为javascript函数的参数。

修改

在我的研究之后,我发现了这个页面:Mapping server functions to client actions它以某种方式解释了命名函数的目标,即使它没有引导我找到一个有效的解决方案。

1 个答案:

答案 0 :(得分:6)

快速回答

在Lift中休息不一定是无国籍人。如果您使用LiftRules.dispatch.append注册RestHelper,那么它将被有状态地处理,并且会像往常一样通过S对象获得会话信息。

长答案

由于您似乎对此感兴趣,并且之前已经提出过,所以这里有一个关于如何在Lift中注册和调用服务器端功能的更详细说明。如果你有一段时间没有使用Lift,请远离。以下内容不应以任何方式用于评估Lift或其复杂性。这纯粹是图书馆开发者级别的东西,并且大多数Lift​​用户对他们的开发感兴趣而不知道它。

如何运作

当你创建有状态回调时,通常使用SHtml对象中的方法,你真正要做的是在用户会话的上下文中注册S.AFuncHolder类型的对象,每个对象都有一个唯一的ID。在此过程中生成的唯一ID是您遇到类似F96606625700QRXLDO的模式时所看到的。当通过表单post,ajax或其他任何方式提交数据时,Lift将检查这些函数id的请求并执行相关的函数(如果存在)。有几个帮助器提供更多特定类型的AFuncHolder,如S.SFuncHolder(接受单个字符串查询参数)和S.BinFuncHolder(参数是多部分表单数据),但它们都返回Any和后台Lift将收集这些返回值创建适当类型的响应。例如,JsCmd将生成执行命令的JavaScriptResponse。您也可以直接返回LiftResponse。

如何使用

使用S.fmapFunc方法注册AFuncHolders。你会这样称呼它

S.fmapFunc(SFuncHolder({ (str: String) =>
  doSomethingAwesomeWithAString(str)
}))(id => <input type="text" name={id} value=""/>)

第一个参数是你的函数,用正确的* FuncHolder类型包装,第二个参数是一个获取生成的id并输出某些东西的函数。获取输出的某些是您将在页面上包含的内容。它应该以某种方式导致id作为查询参数发送到服务器,以便执行您的函数。

全部放在一起

您可以使用上面的方法进行自己的Ajax调用,但当Lift进行ajax调用时,还有一些其他注意事项:

1)大多数浏览器只允许同时连接到给定域。三个似乎是神奇的数字。 2)AFuncHolders通常会关闭它们所包含的片段的范围,如果一次处理多个ajax请求,每个都在自己的线程中,就会发生不好的事情。

为解决这些问题,liftAjax.lift_ajaxHandler函数会对每个ajax请求进行排队,确保一次只能向服务器发送一个。

这种方法的缺点是,它可能使得难以进行Ajax调用,其结果需要传递给回调。例如,JQuery自动完成功能在接受匹配列表的输入更改时提供回调函数。如果你手动调用LiftAjax.lift_ajaxHandler,你可以提供自己的回调功能,以便成功和错误,我建议您查看浏览器中这些功能的来源,以获取有关它们如何工作的更多信息。

实际上还有更多内容,比如Lift如何在ajax回调中恢复RequestVars(这就是lift_page进来的地方,但这就是我准备在星期六早上用咖啡解释的所有内容:)

祝你的应用好运!