Ajax学习
1. Ajax基本操作
- Ajax实现网页的异步加载,它与服务器端建立数据连接的过程和TCP握手基本相似。
- IE6和IE5对ajax不兼容需要做兼容性处理。
- ajax建立连接后会获得服务器返回的数据。
创建Ajax对象
var xhr = null;
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest(); //IE7+
}else{
xhr = new ActiveXObject('Microsoft.XMLHTTP');//IE5,IE6
}
发送请求
代码
xhr.open(method,url,async);
// method: 请求类型;GET或POST
// url: 文件服务器的位置
// async: true(异步)或false(同步)
xhr.send(string);
// 将请求发送到服务器
// string:仅用于POST请求
-
什么时候适合使用POST请求
- 无法使用缓存文件(发送文件或者cookie时)
- 向服务器发送大量数据(POST没有数据量的限制)
-
GET请求代码
xhr.open('GET','./handler.php',true);
xhr.send();
- POST请求代码
xhr.open('POST','./handler.php',true);
xhr.send();
如果想要像HTML表单那样用POST提交数据,需要setRequestHeader()
来添加HTTP头,然后在send()
方法中放置要发送的数据。
xhr.open('GET','./handler.php',true);
xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
xhr.send('id=1234&uname=foo');
NOTE:
当open()
函数中设置async
为true
时,需要监听ajax与服务器的连接状态,当连接成功后再做操作。
当open()
函数中设置async
为false
时,不需要监听状态,因此这时ajax程序变成了普通的js程序,它是按照js程序的解释顺序执行的。
Ajax连接服务器的几个状态
onreadystatechange 事件
每当服务器端和客户端的连接发生变化时(readyState属性值发生变化时)就会触发onreadystatechange 事件
。XMLHttpRequest
对象有两个属性记录与服务器的连接状态。
- readyState
- 0: 请求未初始化
- 1:服务器连接建立
- 2:请求已接受
- 3:请求处理中
- 4:请求已完成且响应已就绪
- status(主要是记录HTTP头中的状态码)
- 200:"OK"
- 404:未找到页面
xhr.onreadystatechange = function(){
if(xhr.readyState==4&&xhr.status==200){
//do something
}
}
服务器端的响应数据
一般使用responseText
和responseXML
属性来存储服务器端返回的数据。
- responseText: 获得字符串形式的响应数据
- responseXML:获得XML形式的响应数据
var data = xhr.responseText;
2. Ajax上传文件
原生ajax实现文件上传功能代码
前端代码
<input type="file" id='file'>
<button>上传</button>
<script>
var file = document.getElementById('file');
var btn = document.querySelector('button');
var xhr = new XMLHttpRequest();
btn.onclick = function(){
var fd = new FormData();
if(file.files[0]){
var checkcode = checkImgType(file.files[0]);
if(checkcode!=0){
alert('上传文件不是图片或上传图片过大');
return;
}
fd.append('userfile',file.files[0]);
}else{
alert('请选择文件后提交!');
return;
}
xhr.open('POST','handler.php',true);
xhr.send(fd);
xhr.onreadystatechange = function(){
if(xhr.readyState==4&&xhr.status==200){
var res = JSON.parse(xhr.responseText);
alert(res.msg);
}else{
alert('上传失败!');
}
}
}
function checkImgType(file){
var exts = ['jpg','png','gif'];
var name = file.name;
var ext = name.substring(name.lastIndexOf('.'));
if(exts.indexOf(ext)==-1){
return 1;
}
var maxsize = 1000;
if(file.size>maxsize){
return 2;
}
return 0;
}
</script>
也可以不使用FormData
来实现文件的上传,但是需要FileReader
API来实现。详细的实现过程参见只使用XMLHttpRequest提交表单上传文件
后端代码
.... //some code
3. jQuery中Ajax的使用
$.ajax({
//请求方式
type:'post',
// 发送数据到服务器时所使用的的内容类型。默认为"application/x-www-form-urlencoded"
contentType:"application/x-www-form-urlencoded",
//发送的数据既可以包含一个字符串像key=value1&key2=value2,也可以使用对象形式{key1:'value1',key2:'value2'},对象形式的数据会在发送时被处理成字符串,如果不做处理需要将processData选项设置成false
data:'key1=value1',
//请求地址
url:'localhost/handler.php',
//请求成功的处理函数
success:function(res){
console.log(res);
},
//请求失败的处理函数
error : function(e){
console.log(e.status);
console.log(e.responseText);
}
})
jQuery ajax方法上传文件
$(function() {
$('button').on('click', function(e) {
var fd = new FormData();
if ($('#file')[0].files[0]) {
fd.append('userfile', $('#file')[0].files[0]);
$.ajax({
url: 'handler.php',
dataType: 'json',
type: 'POST',
async: false,
data: fd,
processData: false, // 使数据不做处理
contentType: false, // 不要设置Content-Type请求头
success: function(data) {
// var res = JSON.parse(data)
// alert(res.msg);
console.log('提交成功');
console.log(data);
},
error: function(res) {
console.log('错误');
// console.log(res);
}
})
}
})
})
4. axios库中Ajax的使用
5. Ajax跨域
JSONP
ajax无法直接访问非同源站点资源,但是script
标签访问文件资源时并没有这种限制。JSONP就是利用了script标签的这种特性。假设站点a.com想要使用站点b.com上的JSON数据,这个加载时异步的,我们用ajax来操作。
客户端代码
<button>操作</button>
<script>
var btn = document.querySelector("button");
btn.onclick = function(e) {
var jsonp = document.createElement("script");
jsonp.type = "text/javascript";
jsonp.src = "http://b.com/jsonp.php?callback=add"
document.querySelector("head").append(jsonp);
}
function add(data) {
console.log(data.a + data.b);
}
</script>
服务器端代码 jsonp.php
<?php
if(isset($_GET['callback'])){
$arr = array('a'=>1,'b'=>2);
$res = json_encode($arr);
$callback = $_GET['callback'];
echo $callback."($res)";
}
?>
可以看出JSONP
并不是利用Ajax来实现异步加载的,只是靠动态添加script标签实现了跨域请求数据,不过这种思想和Ajax异步请求的思想大概是相同的。jQuery的ajax方法,可以直接实现jsonp。
CORS跨域资源共享
这种跨域时利用ajax来实现的,但是需要在服务器端做好设置,也就是将后台响应的HTTP头部信息 Access-Control-Allow-Origin
做好配置。
header('Access-Control-Allow-Origin: http://xxx.com');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept');
跨域的更多介绍详见
跨域资源共享 CORS 详解
网友评论