ajax
服务器介绍
ajax是一个让客户端和服务器进行交互的技术。
何谓客户端?直白点说,可以理解为浏览器,我们平常所写的HTML文件,不管使用什么地址打开,一定是使用浏览器的打开的,所以,我们自己写的HTML代码,可以理解为就是客户端代码。
何谓服务器?服务器分为两个概念:
-
远程电脑
我们打开浏览器的百度网址,会在浏览器中展示百度的网页。这个网页没有在我们自己的电脑上,而是从服务器传送过来的,这里的服务器,其实是一台远程电脑。
-
提供web访问的软件
如果将同桌的电脑理解为服务器的话,为什么我们访问不到同桌电脑上的文件呢?因为,要通过浏览器访问远程电脑的文件,还需要远程电脑开启服务 - 允许别的电脑使用浏览器访问的服务 - web服务。
这个服务如何开启呢?通常需要借助一个软件开启,常见的服务器软件有:nginx、apache、tomcat。。。
随着web服务器的广泛应用,现在有更多的服务器开启方式,例如vscode的live-server插件,也可以开启一个web服务器,让我们可以通过服务器的访问方式来打开HTML页面。
服务器打开页面跟直接双击打开有什么区别?
服务器打开使用的是http协议,直接打开使用的是file协议。协议不同,我们在操作页面的时候,特性也是不同的。例如http协议中的路径和file协议中的路径不同,http能存储数据,file协议不行。。。。
既然我们学习的ajax是让客户端跟服务器进行交互,所以,我们需要在vscode中安装live-server插件,使用http打开我们的页面,来利用http协议实现客户端跟服务器的交互。
总结:
客户端:我们平常开发使用的浏览器
服务器:远程计算机开启了web访问服务软件的计算机 - 开启了web服务器软件的计算机
我们要做什么?我们要在客户端跟服务器进行交互 - ajax
准备工作:在自己计算机上开启两台服务器:
-
vscode安装live server插件,提供一个访问自己项目的服务器
-
安装nodejs,开启server文件夹中用nodejs写好的服务器
用ajax要做的就是,vscode提供的这个服务器(自己项目)访问server文件夹中的服务器数据
ajax介绍
ajax,全称:async javascript and xml
,是一个客户端主动跟服务器进行通信的技术。
ajax能做什么?
ajax可以让网页在不刷新,不跳转的情况下对服务器发起请求。
-
可以告诉服务器某些事件,比如,告诉服务器当前商品又被访问了一次,访问量应该自增了
-
可以给服务器传送数据,比如,告诉服务器又有人来注册了 ,应该把这个账号保存起来
-
可以跟服务器索要数据,比如,我们可以通过请求让服务器给响应一些商品数据,来渲染页面。
ajax有什么好处?
通常情况下,客户端对服务器发请求有很多种方式,比如:直接输入网址敲回车、点击a标签跳转、表单提交跳转、link标签引入css文件、script标签引入js文件、img标签引入图片文件。。。。但这些方式造成的后果都是页面需要跳转,ajax比上述方式好的地方在于不用跳转就能发送请求。例如:京东的评论分页、网易的用户名是否被注册的验证。
ajax语法
ajax发送请求类似于我们打电话的过程,共分为4个步骤:
-
创建ajax对象 - 创建一部电话
var xhr = new XMLHttpRequest()
-
设置请求地址和请求方式 - 输入号码选择联系人
xhr.open(请求方式, 请求地址)
请求方式:get/post
-
发送请求 - 拨号
xhr.send()
-
监听请求状态,接收响应内容 - 将电话放在耳旁,监听对方接听状态和声音
xhr.onreadystatechange = function(){ // 监听到请求完成 - ajax对象的请求状态 0 1 2 3 4 if(xhr.readyState === 4){ // 监听到响应成功 - ajax对象的status 2开头就成功了 if(xhr.status >= 200 && xhr.status < 300){ // 接收响应的数据 var res = xhr.responseText } } }
监听状态的最终目的是接收到响应回来的数据,要先判断是否请求完成,然后再判断这次完成的请求是成功的还是失败的。
ajax的readyState状态:0 1 2 3 4
0表示ajax对象创建好了,但是还没有设置请求的方法和地址
1表示对象创建了,已经设置了请求方式和请求地址,但是还没有发送请求
2表示请求发送了,还没有传回数据
3表示数据正在传送中
4表示数据传送完成
ajax的status:
1开头的表示请求正在进行中
2开头表示成功
3开头缓存和重定向
4开头表示客户端错误,比如请求地址错误
5开头表示服务器错误
请求地址和请求方式由被请求方决定,即接口。
接口需要将目标服务器启动起来。服务器由nodejs创建,所以需要先安装nodejs软件。
根据接口文档进行练习ajax请求。
请求方式分为get和post。
get请求要给服务器发送参数就要带在地址后面。
xhr.open('get', '地址?键=值&键=值')
post请求给服务器带参数,要带在send方法中,且需要先设置请求头:
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencode')
xhr.send('键=值&键=值')
测试请求
测试请求1:
var xhr = new XMLHttpRequest;
xhr.open('get', 'http://localhost:8888/test/first')
xhr.send()
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status>=200 && xhr.status<300){
var res = xhr.responseText
console.log(res);
}
}
}
测试结果:
测试请求2:
var xhr = new XMLHttpRequest // 如果构造函数不需要传参,就可以省略()
xhr.open('get', 'http://localhost:8888/test/second')
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status>=200 && xhr.status<300){
var res = xhr.responseText;
console.log(res);
}
}
}
xhr.send()
测试结果:
像对象的字符串 - json字符串(像数组的字符串也是json字符串)
json字符串转成json对象或数组 - JSON.parse(json字符串)
var res = xhr.responseText;
console.log(res);
var obj = JSON.parse(res)
console.log(obj);
转换结果:
对象或数组 转成 json字符串 - JSON.stringify(对象/数组)
console.log(obj);
console.log( JSON.stringify(obj) );
转换结果:
测试请求3 - get请求传递数据 - 数据放在地址后:
// get请求传递数据,数据就在地址的?后面
xhr.open('get','http://localhost:8888/test/third?name=张三&age=20');
xhr.send()
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status>=200 && xhr.status<300){
var res = xhr.responseText;
res = JSON.parse(res)
console.log(res);
}
}
}
请求结果:
测试请求4:post请求传递数据 - 数据要放在send方法中
// post请求 - 客户端给服务器发送数据
var xhr = new XMLHttpRequest;
xhr.open('post','http://localhost:8888/test/fourth');
// post请求客户端传递数据,就在send方法中,参数的形式必须字符串
// post请求要发送数据,在send之前必须添加一个请求头
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
// 字符串的格式:键=值&键=值..
xhr.send(`name=张三&age=12`)
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status>=200 && xhr.status<300){
var res = xhr.responseText;
res = JSON.parse(res)
console.log(res);
}
}
}
请求结果:
get请求和post请求的区别:
-
get请求的数据在地址栏,post请求的数据在send里面
-
post请求比get请求相对安全
-
get请求 数据大小有限制,post 数据大小是没有限制
登录注册练习
注册
布局:
<style>
td:first-child{
text-align: right;
}
</style>
<body>
<form action="">
<table align="center">
<caption><h2>注册</h2></caption>
<tr>
<td>用户名:</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td>确认密码:</td>
<td><input type="password" name="repass"></td>
</tr>
<tr>
<td>用户昵称:</td>
<td><input type="text" name="nickname"></td>
</tr>
<tr>
<td></td>
<td><input type="submit"></td>
</tr>
</table>
</form>
</body>
布局效果:
表单校验:
验证数据提示的时候,使用alert提示:
// 事件对象阻止默认行为
window.event.returnValue = false
// 验证用户名
var usernameReg = /^[a-z0-9]\w{4,11}$/
// 验证
if(!usernameReg.test(usernameInput.value)){
alert('用户名不符合规则')
return false
}
// 验证密码
var passwordReg = /\w{6,12}/
// 验证
if(!passwordReg.test(passwordInput.value)){
alert('密码不符合规则')
return false
}
// 确认密码
if(repassInput.value != passwordInput.value){
alert('两次密码输入不一致')
return false
}
// 昵称验证
if(nicknameInput.value.trim() === ''){
alert('昵称不能为空')
return false
}
// console.log('验证通过');
ajax请求:
// ajax请求
var xhr = new XMLHttpRequest;
xhr.open('post','http://localhost:8888/users/register');
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
xhr.send(`username=${usernameInput.value}&password=${passwordInput.value}&rpassword=${repassInput.value}&nickname=${nicknameInput.value}`)
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status>=200 && xhr.status<300){
var res = xhr.responseText;
res = JSON.parse(res)
// console.log(res);
var {code, message} = res;
if(code === 1){
alert(message)
// 跳转到登录页面
location.href = "./09-登录.html"
}else{
alert(message)
}
}
}
}
登录
布局:
<style>
td:first-child{
text-align: right;
}
</style>
<body>
<form action="">
<table align="center">
<caption><h2>登录</h2></caption>
<tr>
<td>用户名:</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td></td>
<td><input type="submit"></td>
</tr>
</table>
</form>
</body>
登录逻辑:
// 获取元素
var form = document.querySelector('form');
var username = document.querySelector('[name="username"]');
var password = document.querySelector('[name="password"]');
// 绑定事件
form.onsubmit = function(){
// 验证表单
if(username.value.trim() === '' || password.value.trim() === ''){
alert('用户名和密码都不能为空')
return false
}
// 发送请求
var xhr = new XMLHttpRequest;
xhr.open('post','http://localhost:8888/users/login');
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
xhr.send(`username=${username.value}&password=${password.value}`)
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status>=200 && xhr.status<300){
var res = xhr.responseText;
res = JSON.parse(res)
var {message, code} = res
// console.log(res);
if(code === 1){
alert(message)
}else{
alert(message)
}
}
}
}
// 阻止默认行为
return false
}