ajax 基础原理
(一) json 是什么?
1. javaScript 对象表示法(JavaScript Object Notation) 简称JSON,是一种轻量级的数据交换格式。
2. 基于javaScript 的对象字面量表示法,对于语言却是无关的。
Json 的语法:
Json 以键值对的形式出现:
var jsonobject = '{"key1":"value1","key2":"value2"}'
键: 带双引号的名字。值:可以是任意类型的值。键和值之间使用:隔开
案例:
// json 是什么? 就是一种数据交换格式,必须要按照下面的格式去写
// 注意:key 值必须是双引号引起来 value 可以是下面任意类型。
/* 值得类型:
数字(整数或浮点数)
字符串(在双引号中)
逻辑值(true 或 false)
数值(在方括号中)
对象(在花括号中)
NULL
一个具体的函数或者匿名函数
*/
// json 天生就是一个javascript 对象。
var jstu = '{"name": "李海鹏", "age": 37}';
console.log(jstu);
使用: 后台返回给前台的数据是文本格式,字符串类型。
后台返回的数据如何使用? 可以把json 格式的字符串转换成对象。就可以通过对象. 属性的形式来访问。
var obj = JSON.parse(jstu);
console.log(obj.name);
结果: name 的值。
总结:
1.json 是一种文本格式,你就要按照它的格式来写
2. json 字符串和对象的转换,转换成对象的目的,取相应的数据(小强)
3. json.parse 把字符串解析成对象; json.stringify 把对象转成字符串JSON 格式
4. Json 是一个内置的对象 和array, date 这些对象是一样的。
//序列化: 对象转化成字符串。
var obj = JSON.stringify(jstu);
console.log(typeof obj);
结果:string
(二) 获取用户的名称是否正确 form 版本
服务器端:
/**
* Created by Administrator on 2019-8-4.
*/
var http = require('http');
var url = require('url');
var fs = require('fs');
var querystring = require('querystring');
var app = http.createServer(function(req,res){
//url路由
res.setHeader("Content-Type","text/html;charset=utf-8");
var url_obj = url.parse(req.url);
if(url_obj.pathname === '/')
{
fs.readFile('./index.html','utf-8',function(err,data){
if(!err){
res.write(data);
res.end();
}
})
}
// 验证用户是否存在
if(url_obj.pathname === '/getdata')
{ //假如正确的用户是admin
// console.log(url_obj.query);
if (querystring.parse(url_obj.query).username === 'admin')
{
res.write('{"status":1,"message":"用户已注册" }');
res.end();
}
else
{
res.write('{"status":0,"message":"恭喜你可以注册"}');
res.end();
}
}
});
app.listen(3000);
客户端:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<!--当点击按钮的时候,验证用户名是否存在-->
<form action="/getdata" method="get">
用户名:<input type="text" name="username">
<br />
<input type="submit" value="验证">
</form>
</body>
</html>
提出问题:1. jd的注册 不会跳转到其他页面,也不会重新刷新网页 ajax技术
2.form 传统提交: 跳转页面
(三) 用户名是否正确 ajax 版本 无跳转
客户端: ajax
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.mes{
color: red;
}
</style>
</head>
<body>
用户名:<input type="text" id="username"><span class="mes"></span>
<script>
//当input失去焦点,就要去验证用户名是否存在
var oIpt = document.getElementById('username');
var oSpan = document.getElementsByClassName('mes')[0];
oIpt.onblur = function(ev) {
var iptValue = this.value;
//发送数据到后台,没有表单
var xhr = new XMLHttpRequest();
xhr.open('get','/getdata?username='+iptValue,true);
xhr.send();
xhr.onreadystatechange = function(ev2){
if(xhr.readyState===4 && xhr.status===200){
// alert(xhr.responseText);
//xhr.responseText 这个一个json 字符串
// 需要把字符串转化为对象的值来用。对象化
var obj = JSON.parse(xhr.responseText);
oSpan.innerHTML = obj.message;
}
}
}
</script>
</body>
</html>
服务器端:
/**
* Created by Administrator on 2019-8-4.
*/
var http = require('http');
var url = require('url');
var fs = require('fs');
var querystring = require('querystring');
var app = http.createServer(function(req,res){
//url路由
res.setHeader("Content-Type","text/html;charset=utf-8");
var url_obj = url.parse(req.url);
if(url_obj.pathname === '/')
{
fs.readFile('./index.html','utf-8',function(err,data){
if(!err){
res.write(data);
res.end();
}
})
}
// 验证用户是否存在
if(url_obj.pathname === '/getdata')
{ //假如正确的用户是admin
// console.log(url_obj.query);
if (querystring.parse(url_obj.query).username === 'admin')
{
res.write('{"status":1,"message":"用户已注册" }');
res.end();
}
else
{
res.write('{"status":0,"message":"恭喜你可以注册"}');
res.end();
}
}
});
app.listen(3000);
ajax 的执行流程:
AJAX 语法详解:
XMLHttpRequest 对象:XMLHttpRequest 是一个API, 它为客户端提供了在客户端和服务器之间传输数据的功能。它提供了一个通过URL来获取数据的简单方式,并且不会使整个页面刷新。这使得网页只更新一部分页面而不会打扰到用户。XMLHttpRequest 在AJAX中被大量使用。
(四)XMLHttpRequest 对象详解
监听数据的几种状态。
加上try-catch 书写的方式:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.mes{
color: red;
}
</style>
</head>
<body>
用户名:<input type="text" id="username"><span class="mes"></span>
<script>
//当input失去焦点,就要去验证用户名是否存在
var oIpt = document.getElementById('username');
var oSpan = document.getElementsByClassName('mes')[0];
oIpt.onblur = function() {
var iptValue = this.value;
//发送数据到后台,没有表单
var xhr = null;
try{
//xmlhttpRequest 对象,客户端和服务器之间传输数据
//1 .打开浏览器
xhr = new XMLHttpRequest();
}catch(e)
{
xhr = new ActiveXObject('Microsoft.XMLHTTP')
}
//2. 输入网址 open 方式可以指定发送方式和发送数据的地址是否同步
// true 表示用一步的方式发送请求
//alert(xhr.readyState);
xhr.open('get','/getdata?username='+this.value,true);
// 3.点击按钮,要发送数据
xhr.send();
//4. 监听数据 监听的是xhr.readystate 状态
xhr.onreadystatechange = function(ev){
if(xhr.readyState===4 && xhr.status===200){
//status 表示的是http的状态码 200 表示响应正确
alert(xhr.responseText);
//xhr.responseText 这个一个json 字符串,返回的数据放在resposetext 属性里面。
// 需要把字符串转化为对象的值来用。
var obj = JSON.parse(xhr.responseText);
oSpan.innerHTML = obj.message;
// alert(xhr.readyState);
}
}
}
</script>
</body>
</html>
采用 POST数据传输方式来进行前后端交互:
1.服务器端:
/**
* Created by Administrator on 2019-8-4.
*/
var http = require('http');
var url = require('url');
var fs = require('fs');
var querystring = require('querystring');
var app = http.createServer(function(req,res){
//url路由
res.setHeader("Content-Type","text/html;charset=utf-8");
var url_obj = url.parse(req.url);
if(url_obj.pathname === '/user_login')
{
fs.readFile('./index3.html','utf-8',function(err,data){
if(!err){
res.write(data);
res.end();
}
})
}
// 验证用户是否存在
//if(url_obj.pathname === '/getdata')
//{ //假如正确的用户是admin
// console.log(url_obj.query);
// if (querystring.parse(url_obj.query).username === 'admin')
// {
// res.write('{"status":0,"message":"用户名已存在!" }');
// res.end();
// }
//else
// {
// res.write('{"status":1,"message":"恭喜!该用户名未使用,你可以注册."}');
// res.end();
//}
//}
// 验证前端的用户名和密码是否正确
if(url_obj.pathname === '/login' && req.method === 'POST') {
// data end
var post_data = '';
req.on('data',function(chunk){
post_data += chunk;
//console.log(post_data);
});
req.on('end',function(){
// username = xx&password = 11
var obj_post = querystring.parse(post_data);
// 假设正确的用户名和密码是 admin 123
if(obj_post.username === 'admin' && obj_post.password === '123')
{
res.write('{"status":0,"message":"可以登录!" }');
}
else
{
res.write('{"status":1,"message":"用户名和密码错误"}');
}
res.end();
});
}
});
app.listen(3000);
2. 客户端:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
用户名:<input type="text" id="username">
密 码:<input type="password" id="password" >
<input type="button" value="登录" id="btn" >
<script>
// 获取元素
var oBtn = document.getElementById("btn");
var oUser = document.getElementById("username");
var oPass = document.getElementById("password");
//添加点击事件
//oBtn.onclick = function()
oBtn.onclick = function()
// Function httpPost()
{ //发送请求
var xhr = null;
try {
xhr = new XMLHttpRequest();
}catch(e){
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
//打开一个请求的地址,需要新建立后台路由
xhr.open('POST','/login',true);
//发送请求,数据放在哪里?get方式数据在查询字符串中 post 方式数据在请求体中
xhr.setRequestHeader('content-type','application/x-www-form-urlencoded');
xhr.send("username="+oUser.value+"&password="+oPass.value);
// xhr.send("uarname=admin&password=123");
//xhr.send();
// 监听状态 readystate 状态 4 表示数据已经返回成功,可以使用了
xhr.onreadystatechange = function(ev){
if(xhr.readyState === 4 && xhr.status=== 200)
{
//responseText 文本格式,字符串类型,解析成对象后才能使用
//alert(xhr.responseText);
var obj =JSON.parse(xhr.responseText);
if(obj.status === 0)
{
window.location.href = "http://exmail.qq.com";
}else
{
alert(obj.message);
}
}
}
}
</script>
</body>
</html>
(四) 前后端交互显示数据列表
客户端:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<button id="btn">获取数据</button>
<ul id="ul1"></ul>
<script>
// 获取元素
var oBtn = document.getElementById("btn");
//添加点击事件
//oBtn.onclick = function()
oBtn.onclick = function()
// Function httpPost()
{ //发送请求
var xhr = null;
try {
xhr = new XMLHttpRequest();
}catch(e){
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
//打开一个请求的地址,需要新建立后台路由
xhr.open('get','/getNews',true);
//发送请求,数据放在哪里?get方式数据在查询字符串中 post 方式数据在请求体中
// xhr.setRequestHeader('content-type','application/x-www-form-urlencoded');
xhr.send();
// xhr.send("uarname=admin&password=123");
//xhr.send();
// 监听状态 readystate 状态 4 表示数据已经返回成功,可以使用了
xhr.onreadystatechange = function(ev){
if(xhr.readyState === 4 && xhr.status=== 200)
{
//responseText 文本格式,字符串类型,解析成对象后才能使用
//alert(xhr.responseText);
var arr =JSON.parse(xhr.responseText);
var oul = document.getElementById("ul1");
// console.log(obj);
// 创建li 把数据放到li里面去
for(var i=0;i <arr.length;i++){
var oLi = document.createElement("li");
oLi.innerHTML = arr[i].title;
oul.appendChild(oLi);
}
}
}
}
</script>
</body>
</html>
服务器端:
/**
* Created by Administrator on 2019-8-4.
*/
var http = require('http');
var url = require('url');
var fs = require('fs');
var querystring = require('querystring');
var app = http.createServer(function(req,res){
//url路由
res.setHeader("Content-Type","text/html;charset=utf-8");
var url_obj = url.parse(req.url);
if(url_obj.pathname === '/')
{
fs.readFile('./new.html','utf-8',function(err,data){
if(!err){
res.write(data);
res.end();
}
});
}
// 验证用户是否存在
if(url_obj.pathname === '/getdata')
{ //假如正确的用户是admin
// console.log(url_obj.query);
if (querystring.parse(url_obj.query).username === 'admin')
{
res.write('{"status":0,"message":"用户名已存在!" }');
res.end();
}
else
{
res.write('{"status":1,"message":"恭喜!该用户名未使用,你可以注册."}');
}
res.end();
}
// 验证前端的用户名和密码是否正确
if(url_obj.pathname === '/login' && req.method === 'POST')
{
// data end
var post_data = '';
req.on('data',function(chunk){
post_data += chunk;
//console.log(post_data);
});
req.on('end',function(){
// username = xx&password = 11
var obj_post = querystring.parse(post_data);
// 假设正确的用户名和密码是 admin 123
if(obj_post.username === 'admin' && obj_post.password === '123')
{
res.write('{"status":0,"message":"可以登录!" }');
}
else
{
res.write('{"status":1,"message":"用户名和密码错误"}');
}
res.end();
});
}
//返回新闻列表
if(url_obj.pathname === '/getNews')
{
var arr = '['+
'{"title":"前后端交互1","time":"'+new Date().toLocaleDateString()+'"},'+
'{"title":"前后端交互2","time":"'+new Date().toLocaleDateString()+'"},'+
'{"title":"前后端交互3","time":"'+new Date().toLocaleDateString()+'"},'+
'{"title":"前后端交互4","time":"'+new Date().toLocaleDateString()+'"}'+
']';
//console.log(arr);
res.write(arr);
res.end();
}
});
app.listen(3000);
(五) ajax 前后端交互封装方式:
ajax.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>ajax 封装</title> <script src="ajax.js"> </script> </head> <body> <button id="btn">获取数据</button> <ul id="ul1"></ul> <script> // 获取元素 // 每三秒去获取一次服务器的信息 var oBtn = document.getElementById("btn"); //添加点击事件 //oBtn.onclick = function() oBtn.onclick = function() // Function httpPost() { var options= { method: 'get', url:'/getNews', data: '', success: function(data){ var oul = document.getElementById("ul1"); //console.log(data); // 创建li 把数据放到li里面去 for(var i=0;i <data.length;i++){ var oLi = document.createElement("li"); oLi.innerHTML = data[i].title; oul.appendChild(oLi); } } } ajax(options); } // 开启一个定时器 setInterval(function() { var options = { method: 'get', url:'/getNews', data: '', success: function(data){ var oul = document.getElementById("ul1"); //console.log(data); // 创建li 把数据放到li里面去 for(var i=0;i <data.length;i++){ var oLi = document.createElement("li"); oLi.innerHTML = data[i].title; oul.appendChild(oLi); } } } ajax(options); },3000) </script> </body> </html>
ajax.js
/** * Created by Administrator on 2019-8-9. */ /** * 标题: ajax 封装 * @param method 请求的方法 * @param url 请求的地址 * @param data 发送的数据 * @param success 数据请求成功以后,需要处理的业务逻辑, 就是一个函数块 * return undefined */ function ajax(options){ // 给method 默认值 默认值为 get //发送请求 var method = options.method || 'get'; var xhr = null; try { xhr = new XMLHttpRequest(); }catch(e){ xhr = new ActiveXObject('Microsoft.XMLHTTP'); } if(method === 'get') { //打开一个请求的地址,需要新建立后台路由 xhr.open('get',options.url+"?"+options.data,true); //发送请求,数据放在哪里?get方式数据在查询字符串中 post 方式数据在请求体中 // xhr.setRequestHeader('content-type','application/x-www-form-urlencoded'); xhr.send(); } else if(options.method === 'POST') { xhr.open('POST',options.url,true); xhr.setRequestHeader('content-type','application/x-www-form-urlencoded'); xhr.send(options.data); } else { console.log("请求的方式不正确!"); } // xhr.send("uarname=admin&password=123"); //xhr.send(); // 监听状态 readystate 状态 4 表示数据已经返回成功,可以使用了 xhr.onreadystatechange = function( ) { if(xhr.readyState === 4 && xhr.status=== 200) { //responseText 文本格式,字符串类型,解析成对象后才能使用 //alert(xhr.responseText); var arr =JSON.parse(xhr.responseText); options.success && options.success(arr); } } }
node server:
/** * Created by Administrator on 2019-8-4. */ var http = require('http'); var url = require('url'); var fs = require('fs'); var querystring = require('querystring'); var app = http.createServer(function(req,res){ //url路由 res.setHeader("Content-Type","text/html;charset=utf-8"); var url_obj = url.parse(req.url); if(url_obj.pathname === '/') { fs.readFile('./ajax.html','utf-8',function(err,data){ if(!err){ res.write(data); res.end(); } }); } // 验证用户是否存在 if(url_obj.pathname === '/getdata') { //假如正确的用户是admin // console.log(url_obj.query); if (querystring.parse(url_obj.query).username === 'admin') { res.write('{"status":0,"message":"用户名已存在!" }'); res.end(); } else { res.write('{"status":1,"message":"恭喜!该用户名未使用,你可以注册."}'); } res.end(); } // 验证前端的用户名和密码是否正确 if(url_obj.pathname === '/login' && req.method === 'POST') { // data end var post_data = ''; req.on('data',function(chunk){ post_data += chunk; //console.log(post_data); }); req.on('end',function(){ // username = xx&password = 11 var obj_post = querystring.parse(post_data); // 假设正确的用户名和密码是 admin 123 if(obj_post.username === 'admin' && obj_post.password === '123') { res.write('{"status":0,"message":"可以登录!" }'); } else { res.write('{"status":1,"message":"用户名和密码错误"}'); } res.end(); }); } //返回新闻列表 if(url_obj.pathname === '/getNews') { var arr = '['+ '{"title":"前后端交互1","time":"'+new Date().toLocaleDateString()+'"},'+ '{"title":"前后端交互2","time":"'+new Date().toLocaleDateString()+'"},'+ '{"title":"前后端交互3","time":"'+new Date().toLocaleDateString()+'"},'+ '{"title":"前后端交互4","time":"'+new Date().toLocaleDateString()+'"}'+ ']'; //console.log(arr); res.write(arr); res.end(); } if(url_obj.pathname === '/ajax.js') { fs.readFile('./ajax.js','utf-8',function(err,data){ if(!err) { res.write(data); } res.end(); }); } }); app.listen(3000);
总结:
1. json 文本格式 字符串类型:
{“name”:"xiaoli","age":12}
Json.parse 把字符串对象化
Json.stringify 把对象字符串化
数据传输的格式。
2. ajax 异步的javascript
前后端交互的时候使用的技术
3. XMLHttpRequest
var xhr= new XMLHttpRequest
xhr.open('get' , '/getdata', true) 是否异步
xhr.send()
xhr.onreadystatechange = function(){}
xhr.readystate === 4 && xhr.status === 200
4.ajax 封装
ajax ({
method :'get',
url : '/getdata',
data:"username=xiaoqiang&age=13',
success: function(data){ } 当ajax 请求成功以后,返回的数据会放在data里面。