【问题标题】:Synchronous XHR (AJAX) Deprecated?同步 XHR (AJAX) 已弃用?
【发布时间】:2017-01-26 18:40:31
【问题描述】:

我在我的网站上搭建了一个翻译系统(真的是你们开发的),基本上就是一些返回数组的php文件。

你好.php

return [
  'world' => 'Hello, world!'
];

通过类轻松访问

Lang::get('hello', 'world'); // Hello, world!

在构建响应时这一切都很好,但是在某些情况下,我需要在没有请求的情况下显示翻译。例如,我制作了另一个方便的功能,在表单上进行 PHP 验证,并且在发送请求之前自动生成在页面上执行相同验证的 JavaScript 规则,如果验证失败,那么我需要显示适当的消息 -验证失败可能有数百个可能的原因。请注意,这只是一个示例用例,所以我看到的解决方案是:

  • 我可以使用初始请求加载所有的翻译字符串,并准备好显示其中的任何一个。这将浪费大量带宽,因为大多数时候根本不需要这些字符串。我可以更进一步,将它们缓存在本地存储中,但是缓存整个站点的文本内容(可翻译)可能会超过允许的存储量,因此这似乎不太可靠。

  • 无论如何我都可以发送一个请求并检索我需要的翻译,这在示例用例中破坏了进行此类验证的全部意义,但它比前一个解决方案更好,而且如果做得好我可以受益于浏览器的内部缓存,它只会请求翻译一次,并在后续请求中从缓存中加载它们,这听起来不错。

我选择了第二种解决方案,我面临的问题是:

我有一个 JavaScript 函数,我将用伪代码来描述它。

function translate(file, key) {
  if(!storage[file]) {
    storage[file] = sendAjaxAndLoadFileFromServer();
  }

  return storage[file][key];
}

var storage = {};

如果浏览器缓存了请求,我不知道是否需要在页面上进行二级缓存,但它似乎不会造成伤害?我也可以对此发表意见。

现在这可行,因为我正在同步发送 AJAX 请求。但是我在控制台中看到了这条消息:

主线程上的同步 XMLHttpRequest 已被弃用,因为它会对最终用户的体验产生不利影响。如需更多帮助http://xhr.spec.whatwg.org/

继续suggested site 我没有看到任何暗示我不应该使用同步请求的信息,但是这条消息中的不推荐使用这个词让我想到了。

不幸的是,这是我可以实现这个解决方案的唯一方法(通过同步请求),因为这个函数是在需要返回值的地方调用的,比如

new Dialog(translate('world'));

我看不出如何在这种情况下实现承诺或任何东西。

所以问题是:

我可以使用同步 AJAX 请求吗?它们会在不久的将来消失

【问题讨论】:

    标签: javascript php ajax caching


    【解决方案1】:

    恕我直言,没什么好害怕的。它已被弃用,因为它会影响 UI(冻结),但它是 AJAX 的一个功能。但也许你可以用异步的方式来做——显示等待覆盖,收集所有未翻译的消息,然后隐藏覆盖,然后显示你需要的消息。

    根据评论,或许有办法:

    也许你可以让翻译立即返回,但需要回调。每次调用翻译队列字符串来翻译并显示“等待”。在回调中,您会得到翻译后的字符串。

    会有另一个过程——翻译。如果队列不为空,它将定期转换排队的字符串(例如每 10 毫秒),并为每个字符串调用注册回调。处理完如果队列为空,则隐藏“等待”。

    效果将是 - 第一个翻译请求显示“等待”,最后一个服务请求将其隐藏。所有翻译都是独立的,但分批提供。您需要做的就是将字符串替换逻辑移至回调函数。

    【讨论】:

    • 我不能这样做,因为请求翻译的代码不知道翻译是否已经加载或需要请求。它调用translate 函数并期望返回值。我想不出办法来做到这一点。
    【解决方案2】:

    这将是一个由两部分组成的答案,因为您的问题涉及两个不同的主题。

    同步 AJAX

    它已被弃用是有充分理由的。如果您执行同步 ajax 请求,整个网站会在请求期间冻结。当互联网连接很快并且服务器迅速响应时,这将只需要几毫秒。但是,如果浏览器必须等待更长时间才能响应,则网站可能会冻结几秒钟,这可能会让您的用户感到沮丧。这就是为什么应该避免同步 ajax 请求的原因。

    错误信息的翻译

    您可能还需要考虑以下几个选项:

    • 按语言分段翻译文件。始终仅加载活动语言的文本。如果您支持语言,这只会加载所有文本的 1/5。
    • 按表格或页面或其他相关翻译消息分组对翻译文件进行分段。然后在显示表单之前加载特定于该表单的翻译。这将进一步减少不必要消息的加载。

    请求持续时间 = ping + 响应大小/连接速度

    (对于静态文件) Ping 是向服务器发送请求并取回第一个字节所花费的时间。在光纤上需要 1 毫秒,在移动设备上可能需要数百毫秒。在 100ms ping 和 100kB/s 带宽的 3G 连接上,以下两者都需要 200ms:

    • 加载 10kB 数据(ping 100ms + 传输 100ms = 200ms)
    • 发送两个请求,每个请求几乎不传输数据(ping 100ms + ping 100ms = 200ms)

    因此,选择一次为多条消息加载翻译的解决方案可能是完全可以接受的,因为您可以避免因为服务器和客户端之间的 ping 而浪费时间。

    【讨论】:

      猜你喜欢
      • 2015-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-16
      • 2015-12-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多