AJAX的学习、
一,XHR简介
- 在XHR诞生前,网页要获取客户端和服务器的任何状态更新,都需要刷新一次,在XHR诞生后就可以完全通过JS代码异步实现这一过程。
- HR是一种浏览器API,极大简化了异步通信的过程,开发者并不需要关注底层的实现,因为浏览器会为我们完成这些工作,如连接管理、协议协商、HTTP请求格式化等等。
- XMLHttpRequest 对象提供了对 HTTP 协议的完全的访问,包括做出 POST 和 HEAD 请求以及普通的 GET 请求的能力。XMLHttpRequest 可以同步或异步地返回 Web 服务器的响应,并且能够以文本或者一个 DOM 文档的形式返回内容。
原创链接
二,AJAX的简介
- AJAX 可以用于创建快速动态的网页。
- AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
- AJAX = 异步 JavaScript 和 XML。
- AJAX 是一种用于创建快速动态网页的技术。
通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
注意:Ajax 不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的Web应用程序的技术。三,AJAX的构造
四,XHR创建 XMLHttpRequest 对象
支持大部分浏览器和IE7+
1
variable=new XMLHttpRequest();
老版本的 Internet Explorer (IE5 和 IE6)
1
variable=new ActiveXObject("Microsoft.XMLHTTP");
一,对象创建实例
浏览器兼容
1 | var xmlhttp; //定义一个变量用于后面存储对象 |
二,XHR请求
1.AJAX - 向服务器发送请求
解释:XMLHttpRequest 对象用于和服务器交换数据。
当你的页面全部加载完毕后,客户端会通过 XMLHttpRequest 对象向服务器请求数据,服务器端接受数据并处理后,向客户端反馈数据。
2.向服务器发送请求
get请求代码:1
2xmlhttp.open("GET","ajax.txt",true);
xmlhttp.send();
避免得到的是缓存的结果
只需要在后面加上?t=”+Math.random();如:1
URL:"ajax.txt?t="+Math.random(),
方法解释:
open(method,url,async)
method:请求的类型;GET 或 POST
url:文件在服务器上的位置
async:true(异步)或 false(同步)send(string)
将请求发送到服务器。string:仅用于 POST 请求
在get中一般不填或null.get请求的特点
GET 请求可被缓存
GET 请求保留在浏览器历史记录中
GET 请求可被收藏为书签
GET 请求不应在处理敏感数据时使用
GET 请求有长度限制
GET 请求只应当用于取回数据- 希望通过 GET 方法发送信息,请向 URL 添加信息
1
2xmlhttp.open("GET","demo_get2.html?fname=Henry&lname=Ford",true);
xmlhttp.send();
post请求代码1
2xmlhttp.open("POST","demo_post.html",true);
xmlhttp.send();
如果需要像 HTML 表单那样 POST 数据,请使用 setRequestHeader() 来添加 HTTP 头。然后在 send() 方法中规定您希望发送的数据:1
2
3xmlhttp.open("POST","ajax_test.html",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("fname=Henry&lname=Ford");
- setRequestHeader(header,value)
向请求添加 HTTP 头。
header: 规定头的名称
value: 规定头的值三,POST中的setRequestHeader(header,value)详解
1、XMLObject.setRequestHeader “CONTENT-TYPE”, “application/x-www-form-urlencoded”
CONTENT-TYPE是什么意思,application/x-www-form-urlencoded是什么意思?
解答:通常在HTTP协议里,客户端像服务器取得某个网页的时候,必须发送一个HTTP协议的头文件,
告诉服务器客户端要下载什么信息以及相关的参数,如
GET /bb.asp?www=1234 HTTP/1.1
Accept: /
Accept-Language: zh-cn
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)
Host: www.e4j.cn:89
Connection: Keep-Alive
Cookie: %C3%F7%CC%EC=%B0%CB;ASPSESSIONIDASDBSDRR=BLEDBIBBCGKBJAKJCFEJKGII
2,XMLObject.setRequestHeader “CONTENT-TYPE”, “application/x-www-form-urlencoded”
setRequestHeader “Connection”, “close”
这时HTTP头信息就应该是这样了:
GET /bb.asp?www=1234 HTTP/1.1
Accept: /
Accept-Language: zh-cn
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)
CONTENT-TYPE:application/x-www-form-urlencoded
Host: www.e4j.cn:89
Connection: close
Cookie: %C3%F7%CC%EC=%B0%CB;ASPSESSIONIDASDBSDRR=BLEDBIBBCGKBJAKJCFEJKGII
关于更多setRequestHeader
- POST请求的特点
POST 请求不会被缓存
POST 请求不会保留在浏览器历史记录中
POST 不能被收藏为书签
POST 请求对数据长度没有要求
四,用GET 还是 POST?
与 POST 相比,GET 更简单也更快,并且在大部分情况下都能用。
然而,在以下情况中,请使用 POST 请求:
无法使用缓存文件(更新服务器上的文件或数据库)
向服务器发送大量数据(POST 没有数据量限制)
发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠
五,XHR响应
1.AJAX服务器响应
由于 HTTP 响应是由服务端发出的,并且服务器做出响应需要时间(比如网速慢等原因),所以我们需要监听服务器响应的状态,然后才能进行处理。
服务器响应
如需获得来自服务器的响应,请使用 XMLHttpRequest 对象的 responseText 或 responseXML 属性。
- responseText
获得字符串形式的响应数据。
使用:如果来自服务器的响应并非 XML,请使用 responseText 属性。
实例代码:1
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
提示:对于 responseText 属性,只有当 readyState 属性值变为4时,responseText 属性才可用,因为这表明AJAX请求已经结束!
responseXML
获得 XML 形式的响应数据。
如果来自服务器的响应是 XML,而且需要作为 XML 对象进行解析,请使用 responseXML 属性:response
this.response获取到的结果会根据this.responType的变化而变化六,客户端的捕获
- AJAX - onreadystatechange 事件
当发送一个请求后,客户端需要确定这个请求什么时候会完成,因此,XMLHttpRequest对象提供了 onreadystatechange 件机制来捕获请求的状态,继而实现响应。
当请求被发送到服务器时,我们需要执行一些基于响应的任务。
每当 readyState 改变时,就会触发 onreadystatechange 事件。
readyState 属性存有 XMLHttpRequest 的状态信息。
属性介绍
- onreadystatechange
存储函数(或函数名),每当 readyState 属性改变时,就会调用该函数。 - readyState
存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。
- 0: 请求未初始化
- 1: 服务器连接已建立
- 2: 请求已接收
- 3: 请求处理中
- 4: 请求已完成,且响应已就绪
- status
200: “OK”
404: 未找到页面
当 readyState 等于 4 且状态为 200 时服务器响应已做好被处理的准备时所执行的任务
注意
onreadystatechange 事件被触发 5 次(0 - 4),对应着 readyState 的每个变化
- 0:请求未初始化,还没有调用 open()。
- 1:请求已经建立,但是还没有发送,还没有调用 send()。
- 2:请求已发送,正在处理中(通常现在可以从响应中获取内容头)。
- 3:请求在处理中;通常响应中已有部分数据可用了,没有全部完成。
- 4:响应已完成;您可以获取并使用服务器的响应了。
五,AJAX中需要记的数字
Http的状态码含义。
1**
信息,服务器收到请求,需要请求者继续执行操作2**
成功,操作被成功接收并处理3**
重定向,需要进一步的操作以完成请求301 Moved Permanently
。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替302 Moved Temporarily
。与301类似。但资源只是临时被移动。客户端应继续使用原有URI304 Not Modified
。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源。
4**
客户端错误,请求包含语法错误或无法完成请求400 Bad Request
由于客户端请求有语法错误,不能被服务器所理解。401 Unauthorized
请求未经授权。这个状态代码必须和WWW-Authenticate报头域一起使用403 Forbidden
服务器收到请求,但是拒绝提供服务。服务器通常会在响应正文中给出不提供服务的原因404 Not Found
请求的资源不存在,例如,输入了错误的URL
5**
服务器错误,服务器在处理请求的过程中发生了错误500 Internal Server Error
服务器发生不可预期的错误,导致无法完成客户端的请求。503 Service Unavailable
服务器当前不能够处理客户端的请求,在一段时间之后,服务器可能会恢复正常。
可以参考此篇文章
状态码 | 解释 |
---|---|
1 | 请求收到,继续处理 |
2 | 操作成功并处理 |
200 | 交易成功 |
302 | 在其他地址发现请求数据 |
400 | 错误请求,服务器无法理解 |
401 | 请求授权失败 |
403 | 请求收到,但不给服务 |
404 | 资源不存在 |
500 | 服务器发生错误 |
六,JQuery中的ajax
一,jq中一些ajax的参数
1 | method //数据的提交方式:get和post |
例子1
2
3
4
5
6
7
8
9
10
11
12
13var a=$.ajax({
type:"get",
url:"../test.php",
async:true,
success: function(){//请求成功的回调函数
$("#p").html("请求成功!")
}
});
$(function(){
setTimeout(function(){
$("#c").html(a.responseText)
},4000)
})
七,ajax的跨域
一,同源
解释: ajax默认访问同源数据,所谓同源就是同协议,同域名,同端口。如果请求非同源的会报错。
ajax只能访问同源
二,script标签访问不同源
访问不同源,我们可以使用script标签,将script中的src设置为不同源的数据,js,php等等
如下列例子是通过访问不同源的数据(即跨域访问)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>淘宝提示词</title>
</head>
<body>
<input type="text" id="keyword" placeholder="请输入关键字"/>
<input type="button" id="btn" value="查询"/>
<div class="box"></div>
<script>
var btn = document.getElementById("btn");
btn.onclick = function(){
var keyWord = document.getElementById("keyword").value;
//创建节点将外源的数据传入此处
var script = document.createElement("script");
script.src = "https://suggest.taobao.com/sug?q="+keyWord+"&callback=haha";
//利用window的
window["haha"] = function(data){
var list = "<ul>";
for(var i=0; i<data.result.length; i++){
var temp = data.result[i];
var tempSug = temp[0];
list += "<li>"+tempSug+"</li>";
}
list += "</ul>";
var box = document.querySelector(".box");
box.innerHTML = list;
};
var head = document.querySelector("head");
head.appendChild(script);
};
</script>
</body>
</html>
新学的window属性
window[“haha”] = function(data){};
这个相当于一个方法,本例子的hahaa是callback的回调函数自定义。
三,跨域的封装(script)
跨域封装.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39function myAjax(obj){
var defaults = {
type:"get",//传递数据类型
url:"#",//跨域地址名
data:{},//访问数据
jsonp:"callback",//回调函数
jsonpCallback:"hao",//回调函数名
success:function(data){ //服务器返回方法
},
};
//值覆盖将obj覆盖defaults
for(var key in obj){ //对对象obj进行遍历
defaults[key]=obj[key];//赋值
};
//参数设置
var params = "";
for(var arr in defaults.data){
params += arr +"="+defaults.data[arr]+"&";
}
//去掉最后的&
if(params){
params = params.substring(0,params.length-1);
defaults.url+="?" + params;
}
//添加回调函数值
defaults.url +="&"+defaults.jsonp+"="+defaults.jsonpCallback;
console.log(defaults.url);
//创建script的节点
var script = document.createElement("script");
script.src = defaults.url;
//服务器返回的内容
window[defaults.jsonpCallback] = function(data){
defaults.success(data);//把数据传过去
};
//将script标签放入head标签
var head = document.querySelector("head");
head.appendChild(script);
}跨域的调用
1
2
3
4
5
6
7
8
9<script src="跨域封装.js"></script>
myAjax({
url:"https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su",//外域数据所在库
jsonp:"cb",//回调函数名
jsonpCallback:"hehe", //window["hehe"]名称
data:{wd:keyWord},//关键字
success:function(data){//服务器返回的函数
console.log(data);
});
四,jquery的跨域获取对象
解释:其实jquery也就是js的封装但没有用到script标签,值的注意的是,dataType是必须要设置为jsonp.1
2
3
4
5
6
7
8
9
10$.ajax({
url:"https://suggest.taobao.com/sug",//外域数据
data:{q:val},//搜索关键字
success: function(data){//服务器返回的函数
code....
},
dataType:"jsonp",//服务器返回的数据类型
jsonp:"callback",//回调函数名
jsonpCallback:"haha",//服务器返回时在success中的函数名称
});
例子请求的数据为:https://suggest.taobao.com/sug?q=val&callback=haha
五,jquery的跨域获取json数据
解释:利用jsonp只能获取一个对象的数据,当另域中返回的是一个json数据的话,就不能用jsonp来获取。
这时就需要利用后台来获取数据然后返回前台数据具体如下:
后台获取1
2
3
4
5
6
7
8
9
10
11
12
13
14<?php
header("Content-Type:text/html;charset=utf-8");
$province =$_GET["province"];
$city = $_GET["city"];
//将中文编码转为encode编码使能够访问到数据:
$pro = urlencode($province);
$ci = urlencode($city);
//将文件内容读入一个字符串中
$a = file_get_contents("http://apicloud.mob.com/v1/weather/query?key=2858149d8091c&city=".$ci."&province=".$pro);
//将字符串返
//print_r($a);
echo $a;
?>
注释:此方法是将访问的数据作为字符串的形式来返回,还可以用其他的方法。
前台数据1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26<script type="text/javascript">
var btn = document.querySelector("#c");
btn.onclick =function(){
var pro = $("#a").val();
var ci= $("#b").val();
console.log("你好") ;
$.ajax({
type:"get",
url:"../phpfile/跨域获取json数据.php?province="+pro+"&city="+ci,
async:true,
dataType:"json",
success: function(data){
console.log(data);
if(data.msg=="success"){
$("#d").html("查询结果:"+data.msg+"--天气为:"+data.result[0].weather);
}else{
$("#d").html("请输入正确的省份城市");
}
},
error: function(){
console.log("信息获取失败");
}
});
}
</script>
跨域总结
- 细分可分为script标签,jq利用jsonp跨域,jq利用后端获取json数据。