这个笔记是我学习js犀牛书和一个师姐的慕课网学习笔记和js高级编程三个东西的总结
1,基本概念
超文本传输协议(HyperText Transfer Protocol,HTTP)规定web浏览器如何从web服务器获取文档和向服务器提交表单内容,以及web浏览器如何从Web服务器获取文档和向Web服务器提交表单内容,以及Web如何响应这些请求和提交。
虽然HTTP不在脚本控制下,只是当用户单击链接,提交表单和输入url的时候才发生,但js代码操纵HTTP是可行,但发生以上请求的时候,会初始化HTTP请求。在这两种情况下,浏览器都会重新加载页面,显然这样体验效果不好
AJAX(Asynchronous Javascript and XML)应运而生。这是一种使用脚本操纵HTTP的Web应用架构,而且不会导致页面重载。
而又有一种东西Comet出来了。它和Ajax一样也只是使用脚本操纵HTTP的Web应用架构.但他和Ajax相反。对于Ajax,是客户端从服务端拉数据。在Comet中,是服务端向客户端“推”数据
<template>标签也要登场。此时因为<im g>元素无法实现完整的Ajax传输协议.,通过设置src属性的url然后发起请求。此时,JSON也登场了
实现Ajax技术更简单的实现方式,是XMLHttpRequest对象。这是一种用脚本操纵Http的api。这个API包含了get请求和post请求的能力,同时能用文本或者document对象的形式返回服务器响应。而且不局限XML格式。
2,使用XMLHttpRequest
2.1 新建对象
第一步是要先
var request = new XMLHttpRequest();
//注意,ie6下有不一样的地方
2.2 指定请求
request.open("get","data.json")
GET请求:用于常规请求,适用于当url完全指定请求资源,且请求对服务器没有任何副作用(下面讲述什么叫副作用)以及当服务器的响应是可缓存的
POST请求:常用于HTML表单。在请求主题中包含表单数据且这些数据场存储到服务器的后台数据中( 副作用)
2.3(可选)请求头
request.setRequestHeader("content-Type","text/plain");
- 如果请求头多次,新值不会取代之前的值,相反,HTTP请求还将包含这个头的多个副本或这个头指定的多个值
2.4 向服务器发送
request.send(null);
- get请求没有主体,传递null或省略。post常拥有主体,同时应该匹配使用setREquestHeader()指定的"content-type"的头
3,取得响应
- 异步使用后,send之后要得到返回相应,后面才能继续走。所以必须监听XMLHttpRequest对象上的readystatechange事件。监控这个事件,又必须使用readystate属性
值 | 含义 |
---|---|
0 | open()尚未调用 |
1 | open()已调用 |
2 | 接收到头信息 |
3 | 接收到相应主体 |
4 | 相应完成 |
- 每次readystate的值改变,会触发一次readystatechange事件
*当知道send完成了,就要检测传回来的东西的状态,这时候就要一个status和statusText属性以数字和文本的形式返回状态码
附上一个完整的代码演示
function ajax(url, fnSucc, fnFaild)
{
//1.创建Ajax对象
var oAjax=null;
if(window.XMLHttpRequest)
{
oAjax=new XMLHttpRequest();
}
else
{
oAjax=new ActiveXObject("Microsoft.XMLHTTP");
}
//2.连接服务器
oAjax.open('GET', url, true);
//3.发送请求
oAjax.send();
//4.接收服务器的返回
oAjax.onreadystatechange=function ()
{
if(oAjax.readyState==4) //完成
{
if(oAjax.status==200) //成功
{
fnSucc(oAjax.responseText);
}
else
{
if(fnFaild)
fnFaild(oAjax.status);
}
}
};
}
3.1 同步相应
把false作为第三个参数传递给open(),那么send()方法将会阻塞到完成请求。所以同步相应下就不需要使用事件处理程序。仅仅需要检查status和responseText属性会可以了
3.2与后台交互数据实例
客户端代码之search
document.getElementById("search").onclick=function(){
var request=new XMLHttpRequest();
request.open("GET","server.php? number="+document.getElementById("keyword").value); request.send();
request.onreadystatechange=function () {
if(request.readyState==4){
if(request.status===200){
var data=JSON.parse(request.responseText);//解析服务器返回的信息;
if(data.success){
document.getElementById("searchResult").innerHTML=data.msg; }
else { document.getElementById("searchResult").innerHTML="出现错误:"+data.msg; } }
else{ alert("发生错误"+request.status); }
}
}
}
- 使用JSON.parse():
var jsondata='{"staff":[{"name":"洪七","age":70},{"name":"郭靖","age":35},{"name":"黄蓉","age":30}]}';
var jsonobj=JSON.parse(jsondata);
alert(jsonobj.staff[0].name);
结果:弹出 “洪七”; - Tip:在代码中使用eval是很危险的!特别是用它执行第三方的json数据(其中可能包含恶意代码)时,尽可能使用JSON.parse()方法解析字符串本身方法还可以捕捉json中的语法错误.Eg:
客户端代码之保存
document.getElementById("save").onclick=function(){
console.log('haha');
var add_staff=new XMLHttpRequest();
add_staff.open("POST","server.php");
var data="number="+document.getElementById("staffnumber").value+"&name="+document.getElementById("staffname").value+"&sex="+document.getElementById("staffsex").value+"&job="+document.getElementById("staffjob").value;
add_staff.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); add_staff.send(data);
add_staff.onreadystatechange=function () {
if(add_staff.readyState==4){
if(add_staff.status===200){
var data=JSON.parse(add_staff.responseText);
if(data.success){
document.getElementById("createResult").innerHTML=data.msg;
}
else {
document.getElementById("createResult").innerHTML = "出现错误" + data.msg;
}
}
else{ alert("发生错误"+add_staff.status); }
}
} }
3.3,表单数据的请求头
默认情况下,html表单通过post方法发送给服务器,而编码后的表单数据用做请求主体。
- 编码像这样:
find-pizza&zipcode=032223&radius=1km
响应的头要这样:
Content-Type设置为application/x-www-form-urlencoded
这样就能正确解码 - json
如果是json,响应头要改成application/json