【问题标题】:How to create a utility function for XMLHttpRequest calls?如何为 XMLHttpRequest 调用创建实用函数?
【发布时间】:2013-06-05 05:16:05
【问题描述】:

我在一个页面中多次使用XMLHttpRequest。我手动构建网址,例如

http.onreadystatechange = function() {  
    if (http.readyState === 4){  
        //dosomething  
    }  
};    
http.open('GET','/path/to/page.html?a=1&b=2&c=3&d=4);  
http.send(null);  

这在页面中至少重复了 4 次。所以我正在寻找如何重构它。
我如何使它成为一个单独的实用函数?有没有例如javascript中的可变参数?
将如何传递不同的请求参数以附加到 url?
请注意:我不是在问JQuery。我不问/不使用JQuery 的唯一原因是因为我不知道。
所以请用普通的javascript提供建议

【问题讨论】:

  • 所以你不知道怎么做一个函数,用变量构建一个字符串?
  • @epascarello:什么变量?在一种情况下是a=1&b=2&c=3&d=4,在另一种情况下是e=2,在另一种情况下没有参数。我需要一个可变参数函数对吗?
  • 您可以简单地将数据作为对象传递。可变函数也可以,但在这里不是必需的。
  • @Cratylus:你为什么不简单地将它们作为一个字符串传递给一个参数?
  • @Bergi:你说得有道理。但是单独传递属性似乎更干净。

标签: javascript html ajax xmlhttprequest


【解决方案1】:

您可以在 JavaScript 中定义函数,从而使命令/过程可重用。例如,您可以创建一个函数,该函数接受数据的 key -> value 映射对象和一旦收到响应就应该调用的回调:

function make_request(url, data, done) {
    // initialize XMLHttpRequest object here

    http.onreadystatechange = function() {  
        if (http.readyState === 4){  
            done(http.responseText); // call callback
        }
    };

    // build query string / URL
    // this should be moved in its own function
    var kv = [];
    for (var prop in data) {
        kv.push(encodeURIComponent(prop) + '=' + encodeURIComponent(data[prop]));
    }
    url = url + (url.indexOf('?') === -1 ? '?' : '&') + kv.join('&');

    http.open('GET', url);
    http.send(null);
}

然后会这样调用:

make_request('/path/to/page.html', {a:1, b:2, c:3}, function(response) {
    // do something with the response
});

您可以通过让函数接受参数来配置方法(“GET”或“POST”)、在请求正文中发送的数据、错误回调等,使函数更加通用。 越通用,逻辑通常就越复杂。

Learn more about functions.

另一方面,如果您发现自己不断地向同一个 URL 发出请求并始终以相同的方式处理响应,那么创建另一个函数是有意义的,它只接受要发送的数据并将请求发送到网址。
例如:

function update(data) {
    make_request('/path/to/page.html', data, function(response) {
        // do something with the response
    });
}

那你只需要打电话

update({a: 1});
// or
update({b: 2});

在避免代码重复和代码重复之间需要权衡取舍。如果您在代码中的 100 个不同位置发出相同的请求,那么创建一个额外的函数是值得的。如果你只是这样做五次,那么可能不会。当然,这取决于要复制多少代码。


回答一些问题:

我怎样才能使它成为一个单独的实用函数?

用技术术语来说,你 define a function with function funcName() {...} 并将逻辑放在里面。有关逻辑的示例,请参见上文。

有吗? javascript中的可变参数?

是的。在每个功能中,您都可以访问特殊的arguments variable。这是一个 类数组 对象,其中包含对传递给函数的每个参数的引用。

如何将不同的请求参数传递到附加到 url 中?

以任何你喜欢的方式!您可以传递一个已经正确格式化的字符串,即

"a=1&b=2&c=3"

或者您可以传递一个对象,其中键是参数名称,值是参数值,然后动态构建查询字符串,如上所示。你也可以传递一个嵌套数组,形式为

[['paramName', 'paramValue'], ...]

或像

这样的对象数组
[{name: 'paramName', value: 'paramValue'}, ...]

并做同样的事情。这真的取决于你。

主要目标是减少代码重复。使用数组或对象传递数据是您无法避免的事情。但是从这些数据构建查询字符串可以分解成一个函数。

【讨论】:

  • +1!这个答案对我很有教育意义!谢谢!顺便说一句,如果有空格等,我们需要encodeURIComponent 吗?
  • 空格和任何其他会在此时混淆 URL 的字符(例如,值或名称中的 =&)。
【解决方案2】:

您可以考虑使用jQuery - 它为您抽象了很多内容。

http.onreadystatechange = function() {  
    if (http.readyState === 4){  
        //dosomething  
    }  
};    
http.open('GET','/path/to/page.html?a=1&b=2&c=3&d=4);  
http.send(null);

变成:

$.ajax({
    url: '/path/to/page.html',
    data: { a: 1, b: 2, c: 3, d: 4 }
})
.done(function(r) {
    // do something
});

【讨论】:

  • @Bergi 我做到了;这个问题要求涵盖很多已经涵盖的领域,但没有明显的好处。利用现有的、经过良好测试的跨平台库比自己重新滚动要好得多。
  • OP 说没有 jQuery,因此为什么@Bergi 会问你是否读过它!大声笑
  • @epascarello 我知道;当已经存在经过充分测试的东西时,用您自己的代码覆盖已经覆盖的领域是没有用的。 OP 不知道 jQuery 的事实并不是编写自己的 XHR 库的好理由。
猜你喜欢
  • 2015-09-29
  • 1970-01-01
  • 2018-04-03
  • 1970-01-01
  • 1970-01-01
  • 2018-01-21
  • 2018-10-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多