XMLHttpRequest 2(首先,阅读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 高级功能。
它支持所有*现代浏览器。而且我可以确认,自从 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 传递,它也不会引发错误。
在第一种情况下,错误在as的displayAjax()
下方。this.statusText
Method not Allowed
在第二种情况下,它可以正常工作。如果您传递了正确的发布数据,您必须在服务器端进行检查。
不允许跨域自动抛出错误。
在错误响应中,没有任何错误代码。
只有this.type
which 设置为error。
如果您完全无法控制错误,为什么还要添加错误处理程序?大多数错误都在回调函数的 this 中返回displayAjax()
。
所以:如果您能够正确复制和粘贴 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 做很多事情:
我制作了一个下载管理器(使用简历、文件阅读器和文件系统两侧的范围)、使用画布的各种图像大小调整器转换器、使用 base64images 填充 Web SQL 数据库等等......
但在这些情况下,您应该只为此目的创建一个函数……有时您需要一个 blob、数组缓冲区、您可以设置标题、覆盖 mimetype 等等……
但这里的问题是如何返回 Ajax 响应......(我添加了一个简单的方法。)