jQuery - 使用本机 XHR 和 flXHR (Flash) 回退的 AJAX 请求 - 如何最大程度地减少代码重复?

发布于 2024-12-07 02:12:32 字数 1137 浏览 0 评论 0原文

我需要通过跨域 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 调用,情况很快就会变得更加复杂。

I need to retrieve data via cross-domain XMLHttpRequest. To make this work in (almost) all browsers, I use native XHR first and, if that fails, flXHR.

The (working) code I currently have for this is as follows:

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.');
            }
        });
    }
});

This feels like a lot of code duplication to me, especially in the success handlers. Is there a more efficient way to do this? I'd really prefer to make one $.ajax call that would try both transports in turn, instead of having to use the error handler to make the call a second time. It's not too bad in this example, but rapidly gets more complicated if the success handler is longer or if the success handler has to itself issue another $.ajax call.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

清引 2024-12-14 02:12:32

我创建了一个特定于 jquery 的 flxhr 精简分支,可以简化上面的代码示例。您可以在自述文件的“用法”部分中查看用法示例。

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

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

I've created a jquery-specific and slimmed-down fork of flxhr that simplifies your code sample above. You can see an example of usage in the "Usage" section in the README.

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

In particular, you don't want to waste time waiting for a standard CORS request to fail. It's easy to determine whether flxhr is necessary by testing $.support.cors upfront (no need to override it). Then just use flxhr explicitly where necessary.

远山浅 2024-12-14 02:12:32

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

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

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);
}

我稍微简化了整个事情,但我希望您明白这一点。

编辑

阅读最后一点,也许这会给你一些想法......这是最后一个片段的变体。

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);
}

Why don't you just wrap this in a function by itself? That's after all, how you end up reusing code. You can even pass functions as arguments to make sure that you don't have to repeat this code more than once.

To me this is pretty straight forward but maybe I've misunderstood.

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

Then just pass the success handler once

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

Or if you wanna basically avoid redundant configuration of the ajax call use the first object as a template, like this:

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

I simplified the whole thing a bit, but I hope you get the point.

Edit

Reading that last bit, maybe this will give you some ideas... it's a variation of that last snippet.

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文