在学习AJAX通信技术之前,强烈推荐大家学习一下阮一峰老师的《javaScript教程》
地址:https://wangdoc.com/javascript/bom/xmlhttprequest.html
浏览器与服务器之间,采用 HTTP 协议通信。用户在浏览器地址栏键入一个网址,或者通过网页表单向服务器提交内容,这时浏览器就会向服务器发出 HTTP 请求。
首先,我们来看表单提交内容的方式:
表单即是form标签,它可以包含文本框,复选框,单选框,提交按钮,作用它可以向服务器提交一段在表单元素里面的标签的内容数据.也就是说将文本框,复选框,单选框的内容提交给服务器.
一般情况下表单元素列表的最后会写个 submit 提交按钮,submit 标签不用写任何JS代码就可以在它被点击后把表单里的内容传给服务器.
注意:只有加了name属性的才能提交到服务器.
<form action="doFile.php" method="POST"
<!-- 这里提交的是文件 -->
<input type="file" name="icon">
<input id="name" name="name" type="text" placeholder="分类名称">
<input id="slug" name="slug" type="text" placeholder="slug">
<input id="submitBtn" type="submit">
</form>
//action属性:指定表单提交的哪里
//method属性: 指定提交的方式
//注意在表单元素form里面,如果提交的内容里面有文件的话,需要加上
//enctype="multipart/form-data"这句代码,否则提交文件是不会成功的
表单提交的一些注意点:
// 1.表单提交默认是get方式,如果需要设置为post,改method的方法就可以了
// 2.如果表单需要上传文件,那么需要加上enctype="multipart/form-data",同时上传文件必须是post的方式来提交
// 3.如果上传的文件用了get方式来提交,只能获取到文件名,不能获取到文件的内容
这样的提交表单的做法缺点是:
1.整个网页都要跳转到action指定的网页.
2.如果action没有指定跳转的页面或则为#,只会刷新当前页.
接着,我们来看AJAX提交数据的方法:
AJAX 它是 Asynchronous JavaScript and XML 的缩写,指的是通过 JavaScript 的异步通信,从服务器获取 XML 文档从中提取数据,再更新当前网页的对应部分,而不用刷新整个网页。
JS原生的AJAX请求:
//封装Ajax函数
function ajax (para) {
//创建ajax对象
var xhr = new XMLHttpRequest();
//设置请求头
if(para.type.toLowerCase() == "get" && para.data != undefined) {
//请求方式为get方式
para.url += '?' + para.data;
}
xhr.open(para.type,para.url);
//发送请求
if(para.type.toLowerCase() == 'post') {
//请求方式为post方式
//设置请求头
xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
//发送数据
xhr.send(para.data);
}else {
xhr.send();
}
//监听事件完成
xhr.onload = function(){
//这里吧响应体写死了,不好因为开发者要用这个响应体做自己想做的事情
para.success(xhr.responseText);
}
}
调用原生封装的函数发ajax请求:
//发送get请求
document.getElementById('btn1').onclick = function(){
ajax({
type : 'get',
url : 'a.php',
data : 'name=rose',
success : function(obj){
console.log(obj);
}
});
}
//发送post请求
document.getElementById('btn2').onclick = function(){
ajax({
type : 'post',
url : 'b.php',
data : 'name=jack',
success : function(obj) {
var jsonData = JSON.stringify(obj);
console.log(jsonData);
}
});
}
jQuery发送ajax请求:
三种方式:
$.ajax()
$.get()
$.post()
//后面两种与第一种的区别就是不用加type属性
//传入一个对象
$.ajax({
//请求网址
url: './data.php',
//请求类型
type: 'post',
//服务器响应数据类型,如果是跨域,可以改成jsonp
dataType: 'json',
//发送给服务器的数据(请求体),如果是get请求数据写在url,如果是post才写data属性
data: { id: 1 },
//回调函数:响应回来调用的函数
success: function (data) {
console.log(data)
},
//请求失败触发
error: function (err) {
console.log(err)
}
})
现在我们利用jQuery发送ajax的方法来提交表单:
在提交表单的之前,我们需要学习一个FormData 对象.它的作用:表单数据以键值对的形式向服务器发送,这个过程是浏览器自动完成的。但是有时候,我们希望通过脚本完成过程,构造和编辑表单键值对,然后通过XMLHttpRequest.send()方法发送。浏览器原生提供了 FormData 对象来完成这项工作。(可以利用FormData对象来获取表单里面的内容)
FormData语法知识:
var formdata = new FormData(document.querySelector('form'));
FormData()构造函数的参数是一个表单元素,这个参数是可选的。如果省略参数,就表示一个空的表单,否则就会处理表单元素里面的键值对。
注意点:这里是原生的JS方法,所以参数必须也是JS的元素,比如:
var formdata = new FormData($('form'));
//这里不能使用jQuery的元素
FormData 提供以下实例方法(常用):
// 1.FormData.get(key):获取指定键名对应的键值,参数为键名。
如果有多个同名的键值对,则返回第一个键值对的键值。
// 2.FormData.getAll(key):返回一个数组,表示指定键名对应的
所有键值。如果有多个同名的键值对,数组会包含所有的键值。
// 3. FormData.set(key, value):设置指定键名的键值,参数为键名。
如果键名不存在,会添加这个键值对,否则会更新指定键名的键值。如果第二个参数是文件,还可以使用第三个参数,表示文件名。
// 4.FormData.delete(key):删除一个键值对,参数为键名。
// 5.FormData.append(key, value):添加一个键值对。如果键名重复,则会生成两个相同键名的键值对。如果第二个参数是文件,还可以使用第三个参数,表示文件名。
发送前面表单里面的内容:
$('#submitBtn').on('click',function(e){
//兼容
e = e || window.event;
//阻止表单的默认跳转
e.preventDefault();
//因为涉及到发送文件所以使用ajax2.0的技术
var fm = new FormData( document.querySelector('form'));
//可以查看表单里面提交的内容
// console.log(fm.get('icon'));
// console.log(fm.get('name'));
// console.log(fm.get('password'));
//发送请求,
$.post(
{
url : 'api/updateProfile.php',
//因为fm变量获取到了表单元素里所有的内容,那么data属性就可以直接传递fm
data : fm,
// 告诉jquery,不要把提交的数据对象解析成字符串形式
processData:false,
// 告诉jquery,你不要帮我加请求头,我的fm自己会加
contentType:false,
success : function(objStr) {
if(objStr.trim() == 'ok') {
//成功
location.reload();
}else {
//失败
alert('修改失败');
}
}
}
);
});
/*
上述代码中的注意点:
* 1.必须阻止事件的默认行为,因为submit的默认行为就是提交表单(刷新整个网页),阻止后就可以发送局部请求了.
* 2.var fm = new FormData( document.querySelector('form'));
这行代码就把表单里面的内容获取到了,包括文本内容(name),密码内容(password),以及文件内容(icon)
* 3.因为fm变量获取到了表单元素里所有的内容,那么data属性就可以直接传递fm
*/
其实FormData()方法不只是可以获取表单里的元素,用来提交数据到服务器,更重要的是它可以上传文件.
比如:我们只有一个input输入框,只是用来上传文件,但是它却没有包裹在form表单里面.
//图片预览的功能
<body>
<input type="file" id="file">
<img src="" alt="" id="icon">
</body>
</html>
<script>
document.getElementById('file').onchange = function(){
//创建请求对象
var xhr = new XMLHttpRequest();
//设置请求行
xhr.open('post','file.php');
//创建一个FormData对象
var fm = new FormData();
//添加一个提交到服务器的参数
fm.append('icon',this.files[0]);
//如果用了FormData就不用设置请求头了,因为它内部帮我们设置了
//用了FormData后,直接传递FormData对象
xhr.send(fm);
xhr.onload = function(){
document.getElementById('icon').src = xhr.responseText;
}
}
</script>
//1. var fm = new FormData();创建的空的表单
//2. fm.append('icon',this.files[0]);将文件的内容追加到formdata对象里.这样就可以利用formdata来提交文件了
//3. fm.append('icon',this.files[0]);中的this.files[0]将
//获取到的第一个文件对象传递给表单
补充关于上传文件的一些知识:
js文件处理 File API
支持File API的浏览器有IE10+,Firefox3.5+,Opera10.6+,Safari5+,Chrome。
1.在表单元素上
<input type="fiel" name="file" id="file" />,
可以选择一个或多个文件,通过获取文件元素对象的集合files,来操作每一个对象files[i];
用法:DOM操作
var files=document.getElementById("file");
var file=files.files;//每一个file对象对应一个文件。
file.name//获取本地文件系统的文件名。
file.size//文件的字节大小。
file.type//字符串类型,文件的MIME类型。
file.lastModifiedDate//文件的最后修改时间。(只使用于Chrome浏览器)
2.通过FileReader类型读取文件中的数据(异步文件读取)
FileReader有一下几种读取文件数据的方法
1).readAsText(file,encoding);以纯文本的形式读取文件,将读取到的文件保存到result属性。encoding参数用于指定编码类型,是可选的。
2).readAsDataURL(file);读取文件并将文件数据以URL形式保存到result属性中。(读取图像文件常用方法)
3).readAsBinaryString(file);读取文件并将一个字符串保存在result属性中,字符串中的每个字符表示一字节。
4).readAsArrayBuffer(file);读取文件并将一个包含文件内容的ArrayBuffer保存在result属性中。
3.FileReader提供了几个事件最有用的三个事件,progress,error,load,分别表示是否又读取了新数据,是否发生了错误,是否已经读完整个文件。
var reader=new FileReader();
if(/image/.test(file[0].type)){//操作图像
reader.readAsDataURL(file[0]);
var type='image';
}else{//操作文本
read.readAsText(file[0]);
var type='text';
}
reader.onerror=function(){
//出错时执行
}
reder.onprogress=function(){
//有加载新数据时执行
}
reder.onload=function(){
if(type=='image'){
var html="<img src=\" "+reader.result+" \">";//已经加载完了执行
}else if(type='text'){
var html=reader.result
}
Obj.innerHTML=html;//显示在指定元素对象上
}
demo:发送一个请求,请求包括一个表单以及页面的ID号:
//ajax2.0技术
var fm = new FormData( document.querySelector('form'));
//因为编辑器里面没有name属性,所以利用append方法将盒子里面的内容
//添加到fm对象中
fm.append('content',editor.txt.html());
//将ID也添加到fm对象跟随表单一起发送请求到服务器
fm.append('id',id);
//发请求
$.post(
{
url : "api/updatePosts.php",
//将所有数据放在fm对象中一起提交到服务器
data : fm,
// 告诉jquery,不要把提交的数据对象解析成字符串形式
processData:false,
// 告诉jquery,你不要帮我加请求头,我的fm自己会加
contentType:false,
success : function(strData) {
if( strData.trim() == "ok" ){
//成功的时候,页面跳转
location.href = "posts.html";
}else {
//失败时报错
alert('编辑失败');
}
}
}
);