另外需要注意的是,若在断网状态下调用xhr.send(data)方法,则会抛错:Uncaught NetworkError: Failed to execute 'send' on 'XMLHttpRequest'。一旦程序抛出错误,如果不 catch 就无法继续执行后面的代码,所以调用 xhr.send(data)方法时,应该用 try-catch捕捉错误。
try{ xhr.send(data) }catch(e){ //doSomething... }; xhr.withCredentials与 CORS 什么关系
我们都知道,在发同域请求时,浏览器会将cookie自动加在request header中。但大家是否遇到过这样的场景:在发送跨域请求时,cookie并没有自动加在request header中。
造成这个问题的原因是:在CORS标准中做了规定,默认情况下,浏览器在发送跨域请求时,不能发送任何认证信息(credentials)如”cookies“和”HTTP authentication schemes“。除非xhr.withCredentials为true(xhr对象有一个属性叫withCredentials,默认值为false)。
所以根本原因是cookies也是一种认证信息,在跨域请求中,client端必须手动设置xhr.withCredentials=true,且server端也必须允许request能携带认证信息(即response header中包含Access-Control-Allow-Credentials:true),这样浏览器才会自动将cookie加在request header中。
另外,要特别注意一点,一旦跨域request能够携带认证信息,server端一定不能将Access-Control-Allow-Origin设置为*,而必须设置为请求页面的域名。
xhr相关事件 事件分类
xhr相关事件有很多,有时记起来还挺容易混乱。但当我了解了具体代码实现后,就容易理清楚了。下面是XMLHttpRequest的部分实现代码:
从代码中我们可以看出:
XMLHttpRequestEventTarget接口定义了7个事件:
onloadstart
onprogress
onabort
ontimeout
onerror
onload
onloadend
每一个XMLHttpRequest里面都有一个upload属性,而upload是一个XMLHttpRequestUpload对象
XMLHttpRequest和XMLHttpRequestUpload都继承了同一个XMLHttpRequestEventTarget接口,所以xhr和xhr.upload都有第一条列举的7个事件
onreadystatechange是XMLHttpRequest独有的事件
所以这么一看就很清晰了:
xhr一共有8个相关事件:7个XMLHttpRequestEventTarget事件+1个独有的onreadystatechange事件;而xhr.upload只有7个XMLHttpRequestEventTarget事件。
事件触发条件
下面是我自己整理的一张xhr相关事件触发条件表,其中最需要注意的是 onerror 事件的触发条件。
事件 触发条件
当请求一切正常时,相关的事件触发顺序如下:
触发xhr.onreadystatechange(之后每次readyState变化时,都会触发一次)
触发xhr.onloadstart
//上传阶段开始:
触发xhr.upload.onloadstart
触发xhr.upload.onprogress
触发xhr.upload.onload
触发xhr.upload.onloadend
//上传结束,下载阶段开始:
触发xhr.onprogress
触发xhr.onload
触发xhr.onloadend
发生abort/timeout/error异常的处理
在请求的过程中,有可能发生 abort/timeout/error这3种异常。那么一旦发生这些异常,xhr后续会进行哪些处理呢?后续处理如下:
一旦发生abort或timeout或error异常,先立即中止当前请求
将 readystate 置为4,并触发 xhr.onreadystatechange事件
如果上传阶段还没有结束,则依次触发以下事件:
xhr.upload.onprogress
xhr.upload.[onabort或ontimeout或onerror]
xhr.upload.onloadend
触发 xhr.onprogress事件
触发 xhr.[onabort或ontimeout或onerror]事件
触发xhr.onloadend 事件
在哪个xhr事件中注册成功回调?
评论
查看更多