"right"同步HTTP请求的方式
The "right" way to do synchronous HTTP request
你可能是来骂我的,但这是一个真实的用例。
在线教育的世界里,有SCORM课程。我必须让旧的 SCORM 课程在网站上运行。 SCORM 课程在浏览器中是 "web based" 和 运行,但他们希望在 iframe 中 运行 并且他们希望家长提供 GetValue 方法和 SetValue。
所以这些 SCORM 课程正在做 parent.SetValue("score", "90") 之类的事情并继续前进。如果有任何问题,该功能应该 return "false"。
SCORM 来自 90 年代,在现代网络中我们知道我们必须做 callbacks/promises 而 http 失败 "often"。您可能认为解决方案是一个 SetValue 写入本地数据,然后尝试并重试直到它通过,但 SCORM 课程通常设置为仅在 SetValue 有效时才移动到下一个屏幕,因此您不应该让用户前进,除非 SetValue 实际上保存在服务器上。
TL;DR
假设同步请求是一项要求,那么正确的方法是什么?
到目前为止我知道 $.ajax({async:false ...
但现在浏览器对此发出警告并且听起来他们将忽略您的同步请求。我在想也许使用 websockets 或 web worker 或其他东西是在现代编程中进行同步请求的正确方法。但我不知道如何提出这样的要求。而且SCORM课程的代码不允许更改(它们是用各种课程制作工具生成的)
澄清一下,我可以完全控制 SetValue 函数的实现。
$.ajax({async:false ...
会长期有效吗? (5-10 岁)
注意:在此用例中,完全冻结 UI 直到请求成功或失败是完全可以接受的。这就是课程的假设。
So far I know of $.ajax({async:false…
but now browsers warn about that
这是正确的方法(如果您使用的是 jQuery),它会发送一个同步的 XMLHttpRequest。只是忽略警告。这是一个警告,表明您正在使用您已经知道的过时技术。
and sound like they're going to just ignore your request to be synchronous.
这不太可能。
I am thinking maybe using websockets or web workers or something is the right way to do a syncronous request in modern programming.
不,websockets 和 web worker 总是异步的,你不能用它们让你的异步请求看起来是同步的(事实上没有什么可以让你这样做)。
Will $.ajax({async:false…
work long term? (5-10 years)
我们无法知道(而且 SO 不是 crystal 球)。可能会,尤其是在旧版浏览器中,也可能不会。浏览器供应商不愿意破坏 运行 网络功能的兼容性,并且不时仍然需要同步请求。在某些时候,太少(重要的)网页会使用它(<1%,<1‰,无论他们决定的阈值是多少),浏览器最终将有信心将其删除。到那时,您的企业就会意识到要弃用这些过时的课程制作工具。
根据我学习管理系统的经验,答案是:假装。
您写道:
it is entirely acceptable in this use case to completely freeze the UI until the request either succeeds or fails. That's what the courses assume.
也许您的课程假定了这一点,但在我过去十年中使用的任何学习管理系统中都不是这种情况。
据我所知,学习管理系统不使用同步请求,因为它们会阻止其他脚本,这给人的印象是 page/course 被锁定或损坏。解决方法是通过抽象层(包括 SCORM API)和 return 'true'
对课程使用异步调用,即使您无法验证 AJAX 调用实际上是成功的。
LMS 通常如何处理 SCORM 数据的高级视图:
课程启动时,LMS 从数据库中获取课程的所有现有 SCORM 数据,然后将其放入客户端的 JavaScript 对象中(可通过 SCORM API ).当您通过 SCORM 获取数据时,您通常是在获取这个预加载的 JS 对象中的数据——您不会直接从数据库获得实时响应。因此在使用 SCORM 的 API.GetValue
.
时不需要 AJAX
当您尝试 API.SetValue
时,您最初将 key/value 对存储在 JS 对象中,而不是 SCORM 数据库中。因此,客户端JS对象需要同步指示是否成功存储数据('true'
)或不成功('false'
)。在您尝试使用 API.Commit()
.
将数据 持久化 到数据库之前,数据库 - 和 AJAX - 不会发挥作用
当您尝试从调用 AJAX 的 API.Commit()
获取成功值时,大多数 LMS 会伪造它。他们将执行异步请求以确保课程不会被破坏,因此从 Commit()
编辑的值 return 几乎总是 'true'
。不靠谱。
你可能是来骂我的,但这是一个真实的用例。
在线教育的世界里,有SCORM课程。我必须让旧的 SCORM 课程在网站上运行。 SCORM 课程在浏览器中是 "web based" 和 运行,但他们希望在 iframe 中 运行 并且他们希望家长提供 GetValue 方法和 SetValue。
所以这些 SCORM 课程正在做 parent.SetValue("score", "90") 之类的事情并继续前进。如果有任何问题,该功能应该 return "false"。
SCORM 来自 90 年代,在现代网络中我们知道我们必须做 callbacks/promises 而 http 失败 "often"。您可能认为解决方案是一个 SetValue 写入本地数据,然后尝试并重试直到它通过,但 SCORM 课程通常设置为仅在 SetValue 有效时才移动到下一个屏幕,因此您不应该让用户前进,除非 SetValue 实际上保存在服务器上。
TL;DR
假设同步请求是一项要求,那么正确的方法是什么?
到目前为止我知道 $.ajax({async:false ...
但现在浏览器对此发出警告并且听起来他们将忽略您的同步请求。我在想也许使用 websockets 或 web worker 或其他东西是在现代编程中进行同步请求的正确方法。但我不知道如何提出这样的要求。而且SCORM课程的代码不允许更改(它们是用各种课程制作工具生成的)
澄清一下,我可以完全控制 SetValue 函数的实现。
$.ajax({async:false ...
会长期有效吗? (5-10 岁)
注意:在此用例中,完全冻结 UI 直到请求成功或失败是完全可以接受的。这就是课程的假设。
So far I know of
$.ajax({async:false…
but now browsers warn about that
这是正确的方法(如果您使用的是 jQuery),它会发送一个同步的 XMLHttpRequest。只是忽略警告。这是一个警告,表明您正在使用您已经知道的过时技术。
and sound like they're going to just ignore your request to be synchronous.
这不太可能。
I am thinking maybe using websockets or web workers or something is the right way to do a syncronous request in modern programming.
不,websockets 和 web worker 总是异步的,你不能用它们让你的异步请求看起来是同步的(事实上没有什么可以让你这样做)。
Will
$.ajax({async:false…
work long term? (5-10 years)
我们无法知道(而且 SO 不是 crystal 球)。可能会,尤其是在旧版浏览器中,也可能不会。浏览器供应商不愿意破坏 运行 网络功能的兼容性,并且不时仍然需要同步请求。在某些时候,太少(重要的)网页会使用它(<1%,<1‰,无论他们决定的阈值是多少),浏览器最终将有信心将其删除。到那时,您的企业就会意识到要弃用这些过时的课程制作工具。
根据我学习管理系统的经验,答案是:假装。
您写道:
it is entirely acceptable in this use case to completely freeze the UI until the request either succeeds or fails. That's what the courses assume.
也许您的课程假定了这一点,但在我过去十年中使用的任何学习管理系统中都不是这种情况。
据我所知,学习管理系统不使用同步请求,因为它们会阻止其他脚本,这给人的印象是 page/course 被锁定或损坏。解决方法是通过抽象层(包括 SCORM API)和 return 'true'
对课程使用异步调用,即使您无法验证 AJAX 调用实际上是成功的。
LMS 通常如何处理 SCORM 数据的高级视图:
课程启动时,LMS 从数据库中获取课程的所有现有 SCORM 数据,然后将其放入客户端的 JavaScript 对象中(可通过 SCORM API ).当您通过 SCORM 获取数据时,您通常是在获取这个预加载的 JS 对象中的数据——您不会直接从数据库获得实时响应。因此在使用 SCORM 的 API.GetValue
.
当您尝试 API.SetValue
时,您最初将 key/value 对存储在 JS 对象中,而不是 SCORM 数据库中。因此,客户端JS对象需要同步指示是否成功存储数据('true'
)或不成功('false'
)。在您尝试使用 API.Commit()
.
当您尝试从调用 AJAX 的 API.Commit()
获取成功值时,大多数 LMS 会伪造它。他们将执行异步请求以确保课程不会被破坏,因此从 Commit()
编辑的值 return 几乎总是 'true'
。不靠谱。