首先我们来看看这张图,通过这张图我们可以了解到前后端之间数据提交的详细流程。
用form表单的action实现数据的提交
要素:
- form表单
- action:提交的url
- method:默认就是get
- name属性
- 提交按钮的type=submit,submit和form表单配合使用,会跳转页面
<form action=url>
<input name="username" type="text">
<input name="password" type="text">
<input type="submit">
</form>
通过上述案例,我们明白了如何用表单提交数据,那么我们再看一个问题,如何用表单提交文件呢?在这之前,我们先了解一下post方法。
post提交数据的优点(为什么提交文件要用post方法)
- 提交的数据不在url中,安全性好一点
- post提交数据没有长度限制,浏览器端只要你想,随意添加,服务器端可以选择是否接受这么多的数据
- 如果要上传文件,必须使用post
看到这里就可以解释,为什么用表单提交文件要用post方法了,那么让我们来看看代码的具体实现。
要素:
- form表单
- action:提交的url
- method:post
- type=file
- name属性
- 提交按钮的type=submit,submit和form表单配合使用,会跳转页面
- enctype
默认值是 “application/x-www-form-urlencoded”
提交文件使用"multipart/form-data"
<form action=url method="post" enctype="multipart/form-data">
<!--method 因为默认值是get,所以我们在这里要把它手动设置为post-->
<input name="icon" type="file">
<input type="submit">
</form>
用form表单实现数据的提交的关键点在于,记得书写name值,那么问题来了,为什么要书写name值?
因为form表单通过get提交数据的本质是,在 url 的背后拼接上name=value
格式:url?name=“timo”
在url的后面?key=value
因此我们可以看出,如果我们自己会拼接url,我们也可以实现数据的提交。ajax的get方法就是用url的数据拼接来实现的
用ajax实现数据的提交
- 用get方法提交数据
要素:
- form表单
- method:get
- 提交按钮的type=button,不会跳转页面
sub.onclick = function (){
//1.创建异步对象
var xhr = new XMLHttpRequest();
//2.设置请求行(方式,url)
//get请求,数据都是拼接在url中
//xxx.php?key=value&key2=value2
xhr.open('get','xxx.php?name=jack&skill=painting');
//3.设置请求头(get请求可以不设置,post请求不发送数据也可以省略)
//参数1 键名
//参数2 值
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
//4.注册状态改变事件
xhr.onreadystatechange = function(){
//4.1.判断状态&请求码
if(xhr.readyState == 4&&xhr.status == 200){
// 因为返回的是JSON,所以不需要获取XML,获取Text即可
//console.log(xhr.responseText);
//转化为对应的格式
var obj = JSON.parse(xhr.responseText);//把服务器返回的json转化为对象
if(obj.code!=2000) {
if (obj.code == 1001) {
alert("数据不能为空");
} else if (obj.code == 1002) {
alert("数据不合法");
} else if (obj.code == 3001) {
alert("用户名或密码不正确");
} else {
alert("未知错误");
}
}else{
alert("登陆成功");
}
}
};
//5.发送请求
//post请求发送数据,写在send中
//key = value&&key2=value2
var postData ={username:user.value,password:password.value};//这是发送数据的固定格式
var str =("username="+postData.username+"&"+"password="+postData.password);
xhr.send(str);
};
- 用post方法提交数据
要素:
- form表单
- method:post
- 提交按钮的type=button,不会跳转页面
//绑定点击事件
sub.onclick = function (){
//1.创建异步对象
var xhr = new XMLHttpRequest();
//2.设置请求行(方式,url)
xhr.open('post','xxx.php');
//3.设置请求头(get请求可以省略)
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
//4.注册状态改变事件
xhr.onreadystatechange = function(){
//4.1.判断状态&请求码
if(xhr.readyState == 4&&xhr.status == 200){
// 因为返回的是JSON,所以不需要获取XML,获取Text即可
//console.log(xhr.responseText);
//转化为对应的格式
var obj = JSON.parse(xhr.responseText);//把服务器返回的json转化为对象
if(obj.code!=2000) {
if (obj.code == 1001) {
alert("数据不能为空");
} else if (obj.code == 1002) {
alert("数据不合法");
} else if (obj.code == 3001) {
alert("用户名或密码不正确");
} else {
alert("未知错误");
}
}else{
alert("登陆成功");
}
}
};
//5.发送请求
//post请求发送数据,写在send中
//key = value&&key2=value2
var postData ={username:user.value,password:password.value};//这是发送数据的固定格式
var str =("username="+postData.username+"&"+"password="+postData.password);
xhr.send(str);
};
content-Type和数据传输格式的问题
在这里再提一下我之前踩到一个坑:xhr.send()的数据传输格式老是不正确,具体表现为数据为空,为此我查看了一下network
,注意到,在我传输的JSON数据背后多了一个冒号,为此我查了一下,发现需要把Content-type设置为 ‘application/json’,为此,我特别探究了一下Content-type和xhr.send的使用模式。
- Content-type为 ‘application/json’
xhr.setRequestHeader('Content-type', 'application/json');
=>当Content-type属性的值为 'application/json’时,我们需要传输的就是JSON格式的字符串
var obj = {
username:user.value,
password:password.value
};
var str = JSON.stringify(obj);
xhr.send(str);
- Content-type为’application/x-www-form-urlencoded’
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
=>当Content-type属性的值为’application/x-www-form-urlencoded’是,我们需要传输的是拼接的字符串
var str =("username="+user.value+"&"+"password="+password.value);
xhr.send(str);
ajax中onload
和onreadystate
的区别
我接触onload
和onreadystate
是由于我在学习过程中接触到的这两种代码形式
xhr.onload= function () {
var obj = JSON.parse(xhr.responseText);
var response = obj.results[0].values.text;
addChilds(response,"he");
};
xhr.onreadystatechange= function () {
if(xhr.readyState == 4&&xhr.status == 200){
var obj = JSON.parse(xhr.responseText);
var response = obj.results[0].values.text;
addChilds(response,"he");
}
};
大家看到差别了吗?onreadystatechange
事件的内部加了一个判断条件,这是为什么呢?
这是因为XHR对象有一个readyState属性,该属性表示请求/相应过程的当前活动阶段。这个属性可取的值如下
- 0 未初始化。尚未调用open()方法
- 1 启动。已经调用open()方法,但尚未调用send()方法
- 2 发送。已经调用send()方法,单尚未接收到响应
- 3 接收。已经接收到部分响应数据
- 4 完成。已经接收到全部响应数据,而且已经可以在客户端使用了。
而只要readyState
属性的值由一个值变成另一个值,都会触发一次readystatechange
事件。所以我们如果不加以判断,可能就会因为readyState
事件的多次触发而引起某些bug