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.onprogress
xhr.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
}
}