XMLHttpRequest 2(首先,请阅读Benjamin Gruenbaum和Felix Kling的答案)
如果您不使用jQuery,并且想要在现代浏览器和移动浏览器中使用一个漂亮而简短的XMLHttpRequest 2,我建议您这样使用:
function ajax(a, b, c){
c = new XMLHttpRequest;
c.open('GET', a);
c.onload = b;
c.send()
}
如您所见:
- 它比列出的所有其他函数都要短。
- 回调被直接设置(因此没有额外的不必要的闭包)。
- 它使用了新的 onload (因此您不必检查 readystate && status)。
- 还有一些我不记得的其他情况,这些情况使 XMLHttpRequest 1 变得很恼人。
有两种方法可以获取此 Ajax 调用的响应(使用 XMLHttpRequest 变量名称有三种方法):
最简单的是:
this.response
或者如果由于某些原因,您将回调函数绑定到了一个类:
e.target.response
例子:
function callback(e){
console.log(this.response);
}
ajax('URL', callback);
或者(上面的方法更好,匿名函数总是一个问题):
ajax('URL', function(e){console.log(this.response)});
没有什么比这更简单了。
现在有些人可能会说最好使用onreadystatechange或者甚至是XMLHttpRequest变量名。那是错误的。
查看XMLHttpRequest高级特性。
它支持所有*现代浏览器。我可以确认,因为我自从XMLHttpRequest 2被创建以来一直在使用这种方法。我在使用的任何浏览器中从未遇到任何问题。
如果你想在状态2时获取头信息,onreadystatechange才有用。
使用XMLHttpRequest
变量名是另一个大错误,因为你需要在onload/oreadystatechange闭包内执行回调,否则你就会失去它。
现在,如果您想使用
POST和FormData来完成更复杂的操作,您可以轻松地扩展此函数:
function x(a, b, e, d, c){
c = new XMLHttpRequest;
c.open(e||'get', a);
c.onload = b;
c.send(d||null)
}
再次强调,这是一个非常简短的函数,但它可以执行GET和POST操作。
使用示例:
x(url, callback); // By default it's GET so no need to set
x(url, callback, 'post', {'key': 'val'}); // No need to set POST data
或者传递一个完整的表单元素 (document.getElementsByTagName('form')[0]
):
var fd = new FormData(form);
x(url, callback, 'post', fd);
或设置一些自定义值:
var fd = new FormData();
fd.append('key', 'val')
x(url, callback, 'post', fd);
如您所见,我没有实现同步...这是一件糟糕的事情。
话虽如此...为什么不采取简单的方式呢?
如评论中所述,使用错误处理和同步完全破坏了答案的重点。什么是使用Ajax的正确方式?
错误处理程序
function x(a, b, e, d, c){
c = new XMLHttpRequest;
c.open(e||'get', a);
c.onload = b;
c.onerror = error;
c.send(d||null)
}
function error(e){
console.log('--Error--', this.type);
console.log('this: ', this);
console.log('Event: ', e)
}
function displayAjax(e){
console.log(e, this);
}
x('WRONGURL', displayAjax);
在上面的脚本中,您有一个静态定义的错误处理程序,因此它不会影响函数。错误处理程序也可以用于其他函数。
但是,要真正出现错误,唯一的方法是编写错误的URL,在这种情况下,每个浏览器都会抛出错误。
如果设置自定义标头、将responseType设置为blob数组缓冲区或其他任何操作,则错误处理程序可能很有用...
即使将“POSTAPAPAP”作为方法传递,它也不会抛出错误。
即使将“fdggdgilfdghfldj”作为表单数据传递,它也不会抛出错误。
在第一种情况下,错误位于
displayAjax()
中的
this.statusText
下,显示为“Method not Allowed”。
在第二种情况下,它只是起作用。您必须在服务器端检查是否传递了正确的发布数据。
跨域不允许自动抛出错误。
在错误响应中,没有任何错误代码。
只有设置为
error的
this.type
。
如果您完全无法控制错误,为什么要添加错误处理程序?大多数错误都在回调函数displayAjax()
中返回。
所以:如果您能够正确复制和粘贴URL,则没有必要进行错误检查。 ;)
附注:作为第一个测试,我编写了x('x',displayAjax)...,它完全得到了响应... ??? 所以我检查了HTML所在的文件夹,发现有一个名为“ x.xml”的文件。因此,即使您忘记了您的文件的扩展名XMLHttpRequest 2也会找到它。 我笑了
同步读取文件
不要这样做。
如果您想阻塞浏览器一段时间并同步加载一个漂亮的大型.txt
文件,请不要这样做。
function omg(a, c){
c = new XMLHttpRequest;
c.open('GET', a, true);
c.send();
return c;
}
现在你可以做
var res = omg('thisIsGonnaBlockThePage.txt')
非异步方式下没有其他方法来完成这个任务。(是的,可以使用setTimeout循环...但是认真的吗?)
另一个要点是...如果你在处理API或者自己的列表文件等等,你总是需要为每一个请求使用不同的函数...
只有当你有一个页面,总是加载相同的XML/JSON或者其他内容时,你只需要一个函数。在这种情况下,稍微修改一下Ajax函数,并用你的特殊函数替换b即可。
上述函数是基本用法。
如果您想要扩展该功能...
是的,您可以。
我正在使用许多API,并且我将在每个HTML页面中集成第一个Ajax函数作为答案中的函数,仅使用GET...
但是您可以使用XMLHttpRequest 2执行很多操作:
我制作了一个下载管理器(使用恢复时的两侧范围,filereader和filesystem),各种图像调整大小器转换器(使用画布),使用base64images填充Web SQL数据库等等...
但在这些情况下,您应该仅为此创建一个函数...有时需要blob、array buffers,您可以设置标头,覆盖MIME类型等等...
但问题在于如何返回Ajax响应...(我添加了一种简单的方法。)