# ajax入门(1)
ajax入门(1)
简单了解xmlHttpRequest
网上资料很多,这里举一点基础的。
看这个
https://segmentfault.com/a/1190000004322487 学习了一定时间后发现的一个很详细的,下面也是部分转载这个文章
之后可以学 fetch APIhttps://www.w3ctech.com/topic/854 先给自己挖坑
http 请求
http 请求头有四种类型,分别为
-
通用头部
-
请求头部
-
响应头部
-
内容头部 content-type
内容头部
xmlhttp.open("POST", "/searchMeg", true); // xmlhttp.open("GET", "/test_war_exploded/searchMeg", true); xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); xmlhttp.send("name" + name);content-type 的取值是告诉服务端,你传递过去的内容是啥,你应该准备好如何接受,
取值分析
常用:’application/json’, ’application/x-www-form-urlencoded’,’ multipart/form-data’
-
ajax 默认类型 :application/x-www-form-urlencoded
这时前段可以以对象方式直接给后端,或者以json方式传给后端,当action为get时候,浏览器用x-wwww-form-urlencoded 的编码方式 把 form 数据转换成一个字串 (name1=value&name2=value2),然后把这个字串append到url后面,用?分割,加载这个新的url,当action为post的时候,浏览器吧form数据封装到http body 中,然后发送到server ,在浏览器控制台可以看到他们都是以 from data 的形式展现。
-
ajax 通常会发送get、post 两种请求
-
get 请求时,send 只能传递null 作为参数,因为send()方法是将数据作为请求体发送,而get方法没有请求体。所以send中填了数据也无效。
-
要通过过get请求向后台传输数据 只能在 url 的末尾追加查询字符串 ? & 链接
-
post请求,可以在url后,同时post方法可以利用send()方法来传递请求体数据给后台,通过send()发送的数据也要经过encodeURIComponent方法的处理。不同的是post方法在发送请求前必须先使用setRequestHeader("Content-Type","application/x-www-form-urlencoded")方法来设置表单内容类型,这样数据才会正常的被后台收集到,否则就会出现在"rawPostData"数据中(不同编程语言不同)。
代码源于github上不知道哪个老哥的。冒犯一下。
//ajax异步处理提示数据 function sreach() { document.getElementById("asd").innerHTML="asdasdasd"; var name = document.getElementById("search").value; if (name == "" || name==null) { removeCode(); } else { var xmlhttp; if (window.XMLHttpRequest) { // IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码 xmlhttp = new XMLHttpRequest(); } else { // IE6, IE5 浏览器执行代码 xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { /* * document.getElementById("myDiv").innerHTML = * xmlhttp.responseText; */ var result = xmlhttp.responseText; document.getElementById("asd").innerHTML=result; // var json = eval("(" + result + ")"); // addNode(json); } } xmlhttp.open("POST", "/searchMeg", true); // xmlhttp.open("GET", "/test_war_exploded/searchMeg", true); xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); xmlhttp.send("name=" + name); }
后端回传
常用
response.getWriter().write()
- response.getWriter().writer(),只能打印输出文本格式的(包括html标签),不可以打印对象
客户端演示代码
response.getWriter().print()
- response.getWriter().print(),不仅可以打印输出文本格式的(包括html标签),还可以将一个对象以默认的编码方式转换为二进制字节输出
挖坑
我在idea 上怎么都跑不通这一段。即使加了对应的包(没有缺任何一个。而且网上基本以eclipse….我找不出来原因。)
// response.getWriter().println(""JSONArray.fromObject(list).toString());
这个 markdown 为什么会变成这样啊...
我之前写的$$ $$ 也不支持。。大家可以去我上面贴的第一个人那里去看
事件触发条件
下面是我自己整理的一张xhr相关事件触发条件表,其中最需要注意的是 onerror 事件的触发条件。
| 事件 | 触发条件 |
|---|---|
onreadystatechange |
每当xhr.readyState改变时触发;但xhr.readyState由非0值变为0时不触发。 |
onloadstart |
调用xhr.send()方法后立即触发,若xhr.send()未被调用则不会触发此事件。 |
onprogress |
xhr.upload.onprogress在上传阶段(即xhr.send()之后,xhr.readystate=2之前)触发,每50ms触发一次;xhr.onprogress在下载阶段(即xhr.readystate=3时)触发,每50ms触发一次。 |
onload |
当请求成功完成时触发,此时xhr.readystate=4 |
onloadend |
当请求结束(包括请求成功和请求失败)时触发 |
onabort |
当调用xhr.abort()后触发 |
ontimeout |
xhr.timeout不等于0,由请求开始即onloadstart开始算起,当到达xhr.timeout所设置时间请求还未结束即onloadend,则触发此事件。 |
onerror |
在请求过程中,若发生Network error则会触发此事件(若发生Network error时,上传还没有结束,则会先触发xhr.upload.onerror,再触发xhr.onerror;若发生Network error时,上传已经结束,则只会触发xhr.onerror)。注意,只有发生了网络层级别的异常才会触发此事件,对于应用层级别的异常,如响应返回的xhr.statusCode是4xx时,并不属于Network error,所以不会触发onerror事件,而是会触发onload事件。 |
事件触发顺序
当请求一切正常时,相关的事件触发顺序如下:
- 触发
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.onprogressxhr.upload.[onabort或ontimeout或onerror]xhr.upload.onloadend
- 触发
xhr.onprogress事件 - 触发
xhr.[onabort或ontimeout或onerror]事件 - 触发
xhr.onloadend事件
在哪个xhr事件中注册成功回调?
从上面介绍的事件中,可以知道若xhr请求成功,就会触发xhr.onreadystatechange和xhr.onload两个事件。 那么我们到底要将成功回调注册在哪个事件中呢?我倾向于 xhr.onload事件,因为xhr.onreadystatechange是每次xhr.readyState变化时都会触发,而不是xhr.readyState=4时才触发。
xhr.onload = function () {
//如果请求成功
if(xhr.status == 200){
//do successCallback
}
}
上面的示例代码是很常见的写法:先判断http状态码是否是200,如果是,则认为请求是成功的,接着执行成功回调。这样的判断是有坑儿的,比如当返回的http状态码不是200,而是201时,请求虽然也是成功的,但并没有执行成功回调逻辑。所以更靠谱的判断方法应该是:当http状态码为2xx或304时才认为成功。
xhr.onload = function () {
//如果请求成功
if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
//do successCallback
}
}

浙公网安备 33010602011771号