XMLHttpRequest2(首先,阅读Benjamin Gruenbaum和Felix Kling的答案)
如果你不使用 jQuery 并且想要一个在现代浏览器和移动浏览器中工作的漂亮的简短 XMLHttpRequest 2,我建议这样使用它:
function ajax(a, b, c){ // URL, callback, just a placeholder
c = new XMLHttpRequest;
c.open('GET', a);
c.onload = b;
c.send()
}
如你所见:
- 它比列出的所有其他函数都短。
- 回调是直接设置的(因此没有额外的不必要的关闭)。
- 它使用新的 onload(因此您不必检查 readystate && 状态)
- 还有一些其他情况,我不记得了,这让 XMLHttpRequest 1 很烦人。
有两种方法可以获取此 Ajax 调用的响应(三种使用 XMLHttpRequest var 名称):
最简单的:
this.response
或者如果你出于某种原因bind() 回调一个类:
e.target.response
例子:
function callback(e){
console.log(this.response);
}
ajax('URL', callback);
或者(上面一个更好的匿名函数总是有问题):
ajax('URL', function(e){console.log(this.response)});
没有比这更容易的了。
现在有些人可能会说最好使用onreadystatechange 甚至XMLHttpRequest 变量名。错了。
查看XMLHttpRequest advanced features。
它支持所有*现代浏览器。而且我可以确认,自从 XMLHttpRequest 2 创建以来,我一直在使用这种方法。在我使用的任何浏览器中,我从未遇到过任何类型的问题。
onreadystatechange 仅在您想要获取状态 2 的标头时才有用。
使用 XMLHttpRequest 变量名是另一个大错误,因为您需要在 onload/oreadystatechange 闭包内执行回调,否则您将丢失它。
现在,如果您想要使用 POST 和 FormData 进行更复杂的操作,您可以轻松扩展此函数:
function x(a, b, e, d, c){ // URL, callback, method, formdata or {key:val},placeholder
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){ // URL, callback, method, formdata or {key:val}, placeholder
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' 作为 formdata 传递,它也不会抛出错误。
在第一种情况下,错误位于this.statusText 下的displayAjax() 内,为Method not Allowed。
在第二种情况下,它可以正常工作。您必须在服务器端检查您是否传递了正确的发布数据。
不允许跨域自动抛出错误。
在错误响应中,没有任何错误代码。
只有this.type设置为错误。
如果您完全无法控制错误,为什么还要添加错误处理程序?
大部分错误都在回调函数displayAjax()的this里面返回。
因此:如果您能够正确复制和粘贴 URL,则无需进行错误检查。 ;)
PS:作为第一个测试,我写了 x('x', displayAjax)...,它完全得到了响应...???所以我检查了HTML所在的文件夹,有一个名为'x.xml'的文件。因此,即使您忘记了文件 XMLHttpRequest 2 的扩展名,也会找到它。我笑了
同步读取文件
不要那样做。
如果您想暂时阻止浏览器,请同步加载一个不错的大.txt 文件。
function omg(a, c){ // URL
c = new XMLHttpRequest;
c.open('GET', a, true);
c.send();
return c; // Or c.response
}
现在你可以做
var res = omg('thisIsGonnaBlockThePage.txt');
没有其他方法可以以非异步方式执行此操作。 (是的,使用 setTimeout 循环......但认真吗?)
另一点是...如果您使用 API 或只是您自己的列表文件或任何您总是为每个请求使用不同的函数...
仅当您有一个页面始终加载相同的 XML/JSON 或您只需要一个函数的任何内容时。在这种情况下,稍微修改 Ajax 函数并将 b 替换为您的特殊函数。
以上功能为基本使用。
如果你想扩展函数...
是的,你可以。
我使用了很多 API,我集成到每个 HTML 页面的第一个函数是这个答案中的第一个 Ajax 函数,只有 GET...
但是你可以用 XMLHttpRequest 2 做很多事情:
我制作了一个下载管理器(使用简历、文件阅读器和文件系统两侧的范围)、使用画布的各种图像大小调整转换器、使用 base64 图像填充 Web SQL 数据库等等......
但在这些情况下,您应该只为此目的创建一个函数...有时您需要一个 blob、数组缓冲区、您可以设置标题、覆盖 mimetype 等等...
但这里的问题是如何返回 Ajax 响应...(我添加了一个简单的方法。)