【问题标题】:jQuery - AJAX request using both native XHR and flXHR (Flash) fallback - how to minimize code duplication?jQuery - 使用本机 XHR 和 flXHR (Flash) 后备的 AJAX 请求 - 如何最大限度地减少代码重复?
【发布时间】:2011-09-28 06:50:11
【问题描述】:

我需要通过跨域 XMLHttpRequest 检索数据。为了在(几乎)所有浏览器中实现这一点,我首先使用原生 XHR,如果失败,则使用 flXHR。

我目前拥有的(工作)代码如下:

jQuery.support.cors = true; // must set this for IE to work

$.ajax({
    url: 'http://site.com/dataToGet', 
    transport : 'xhr',
    success: function(data) {
        console.log('Got data via XHR');
        doStuff(data);
    },
    error: function(xhr, textStatus, error) {
        console.log('Error in xhr:', error.message);
        console.log('Trying flXHR...');
        $.ajax({
            url: 'http://site.com/dataToGet',
            transport : 'flXHRproxy',
            success: function (data) {
                console.log('Got data via flXHR');
                doStuff(data);
            },
            error: function (xhr, textStatus, error) {
                console.log('Error in flXHR:', error.message);
                console.log('Both methods failed, data not retrieved.');
            }
        });
    }
});

这对我来说感觉像是很多代码重复,尤其是在成功处理程序中。有没有更有效的方法来做到这一点?我真的更愿意进行一次 $.ajax 调用,轮流尝试两种传输,而不是必须使用错误处理程序来进行第二次调用。在这个例子中并不算太糟糕,但是如果成功处理程序更长或者如果成功处理程序必须自己发出另一个 $.ajax 调用,则会迅速变得更加复杂。

【问题讨论】:

    标签: ajax jquery error-handling cross-domain


    【解决方案1】:

    我创建了一个特定于 jquery 且精简的 flxhr 分支,它简化了您上面的代码示例。您可以在 README 的“使用”部分查看使用示例。

    https://github.com/b9chris/flxhr-jquery-packed

    特别是,您不想浪费时间等待标准 CORS 请求失败。通过预先测试$.support.cors 很容易确定是否需要flxhr(无需覆盖它)。然后在必要时显式使用 flxhr。

    【讨论】:

      【解决方案2】:

      你为什么不把它单独包装在一个函数中呢?毕竟,这就是你最终重用代码的方式。您甚至可以将函数作为参数传递,以确保您不必多次重复此代码。

      对我来说这很简单,但也许我误解了。

      function xhr(success) {
          $.ajax({ 
              success: success, 
              error: function() { 
                  $.ajax({ success: success }) 
              } 
          });
      }
      

      然后只传递一次成功处理程序

      xhr(function(data){/*magic*/});
      

      或者,如果您想基本上避免 ajax 调用的冗余配置,请使用第一个对象作为模板,如下所示:

      function xhr(success) {
          var ajaxParams = { success: success };
          ajaxParams.error = function() { 
              $.ajax($.extend(ajaxParams, { transport: 'xhr' })); 
          }
          $.ajax(ajaxParams);
      }
      

      我把整个事情简化了一点,但我希望你明白这一点。

      编辑

      阅读最后一点,也许这会给你一些想法……这是最后一个 sn-p 的变体。

      function xhr(success) {
          var ajaxParams = { success: success };
          ajaxParams.error = function() { 
              var newParams = $.extend(ajaxParams, { transport: 'xhr' });
              newParams.success = function() {
                  // do something
                  // arguments is a special array, even if no parameters were
                  // defined in any arguments where passed they will be found
                  // in the order they were passed in the arguments array
                  // this makes it possible to forward the call to another 
                  // function
                  success.apply(this, arguments); 
              }
              $.ajax(newParams); 
          }
          $.ajax(ajaxParams);
      }
      

      【讨论】:

      • 我需要将一个函数的结果传递给下一个调用,所以嵌套调用获取所有结果。
      • 除此之外,这就是我一直在寻找的东西——它确实回答了我所写的问题。我只是不知道如何在不使用全局变量的情况下将值从一个成功处理程序传递到下一个。 (这可能是一个单独的问题,但我无法找到它 - 如果你能指出如何做到这一点,那将非常有帮助。)谢谢!
      • 如果您只是在周围的外部范围内声明一个变量,该变量将在后续函数中被捕获。这就是通常所说的闭包。在这种情况下,变量将代表相同的内存位置,因此可用于通信(传递数据)。我相信这类似于您使用全局完成此操作的方式,但范围是有限的,而且它不会污染您程序的其余部分。如果您发布一个新问题,详细说明您认为自己想要做什么,我可能会为您提供一些代码和更好的解释。
      猜你喜欢
      • 1970-01-01
      • 2011-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-11
      • 1970-01-01
      • 1970-01-01
      • 2021-11-01
      相关资源
      最近更新 更多