Fork me on GitHub

AJAX基础

1.前端与后端

前端:指的是一切用户看到的界面,都是属于前端的工作范围,比如浏览器中看到的页面,或是手机里面看到的那些APP...
 
后端:主要是指的与数据库进行交互,向前端开放接口,返回对应的数据
 
 

2.演示浏览器与服务器端的交互

1.我们将写好的页面上传到了服务器,供所有的人来访问
2.用户打开自己电脑中的浏览器,输入域名或IP地址,向服务器发送请求
3.服务器接收到这个请求,进行处理,将用户请求的页面的源代码响应给对应的浏览器
4.浏览器接收到这个响应数据(源代码,html+css+js)后,进行处理,最终将源代码呈现到我们的浏览器上,让我看到真正的页面
5.这就是浏览器与服务器端的一个基本交互过程
 
 

3.实现自身服务器功能的访问

1.将接收到的server.rar文件解压出来
2.在这个文件夹中的views文件夹中新建index.html,写页面基本布局和样式
3.然后双击启动.bat这个文件,表示启动服务器
4.在浏览器输入127.0.0.1:3001/index.html,之后回车,查看页面效果
 
 
 

4.网络相关概念介绍

  • 服务器:就是指专门安装了某些服务功能性质的软件的机器,按功能来区分的话,
    • web服务器,提供页面访问的
    • 数据库服务器,专门用来提供数据访问
    • 邮件服务器,收发网络邮件
  • 客户端:就是指享受提供服务的终端设置,在我们电脑上指的是浏览器
  • IP地址:IP地址是用于定位或标识网络中的终端设备的,终端设备比如:PC,手机,平板,智能家电...
    • 127.0.0.1称为本机回环地址,只要是我们电脑安装了操作系统,就会有一个私有的IP:127.0.0.1
    • localhost:相当于 是我们本机的域,和127.0.0.1是对应的,是等价的
  • 端口: 端口是用来区分电脑中的应用程序的,应用程序如:飞秋,内网通,数据库,淘宝旺旺...
  • 域名:域名其实是和IP对应的,因为IP是四组阿拉伯数字组成 ,没有什么规律,不好记忆,因此人们就给这个IP起了个别名,就是这个域名,用这个域名来代替IP
  • DNS服务器:专门用于解析域名和IP地址之间的映射关系。
  • 端:指的终端或终端设备,比如电脑,手机,智能家电
 
 
 

5.HTTP协议

简单来说,HTTP协议就是一种端与端之间的通讯 协议.
HTTP协议规范了请求和响应的报文格式:
请求报文:
  • 请求行 请求报文主要内容有:请求的方式(get/post),请求的目标地址,协议版本
  • 请求头 是浏览器端发送给服务器端的关于客户端的一些额外数据,比如:发送过去的数据编码方式是什么,客户端的操作系统是什么,客户端用的是什么浏览器
  • 请求体 是客户端浏览器发送给服务器的真正的数据值,比如说:用户名,密码,手机号,爱好 ,家庭地址啊...
响应报文:
  • 状态行 报文内容主要包括: 状态码,状态描述,协议版本
  • 响应头 是服务器端发送给客户端的有关服务器端的一些额外数据,比如:服务器端的软件版本,服务器端的操作系统,服务器端的时间,服务器告诉浏览器端如何解析响应回去的数据(Content-Type)
  • 响应体 服务器端响应给浏览器端的真正的数据(比如可能是源代码,有可能是json格式的具体数据...)
 
 
 

6.异步

同步:同一时间只能做一件事,会阻塞主程序的执行
异步:同一时间可以做多件事情,可以通过异步对象来实现,不会阻塞主程序的执行
 
 

7.前后端数据交互的格式

1.字符串
2.二进制
JSON.parse():可以将字符串数组或字符串对象解析成真正的数组或对象
JSON.stringify():是将真正的数组或对象转换成对应的字符串
 
 
 

8.URL

专业名词叫统一资源定位符,其实就是网址或域名或IP地址等.
 
 
 

9.表单

如果想让将浏览器端的数据收集起来,此时就需要用到form表单.
form标签有两个非常重要的属性:
  • action:表示要提交的服务器地址,如果不写默认是提交给自己
  • method:表示提交的方式,如果不写默认是get
 
 
 

10.get请求的特点

  1. get方式在url后面拼接参数,只能以文本的形式传递数据
  2. 传递的数据量小,4KB左右(不同浏览器会有差异)
  3. 安全性低,会将数据显示在地址栏
  4. 速度快,通常用于对安全性要求不高的请求
 
 
 

11.post请求的特点

1-post 方式 安全性比较高
2-传递数据量大,请求对数据长度没有要求
3-请求不会被缓存,也不会保留在浏览器历史记录中
用于:密码等安全性要求比较高的场合,提交的数据量比较大:发布文章,上传文件。
 
 
 

12.使用异步对象来发送请求

使用异步对象在http协议的基础上来发送请求
  • 1.创建异步对象 var xhr = new XMLHttpRequest()
  • 2.设置请求行 xhr.open()
  • 3.设置请求头
  • 4.设置请求体 xhr.send()
  • 5.监视异步对象的状态 xhr.responseText来接收服务器响应回来的数据

 

13.案例

1.使用AJAX异步对象发送get请求

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>初识AJAX</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      list-style: none;
    }
    
    .box {
      width: 300px;
      height: 300px;
      background-color: pink;
      text-align: center;
      line-height: 300px;
      font-size: 30px;
    }
  </style>
  
</head>
<body>
  <h2>开始学习AJAX技术了,真刺激,我喜欢.</h2>
  <div class="box">0</div>
  <input type="button" value="使用AJAX异步加载名字" id="btn">
  <ul></ul>

  <script>
    // 查找元素
    var btn = document.querySelector('#btn');
    var box = document.querySelector('.box');
    var ul = document.querySelector('ul');
    
    // 设置一个定时器让盒子中的计时一直增加
    var num = 0;
    setInterval(function(){
      num++;
      box.innerHTML = num;
    },1000);

    // 给按钮绑定点击事件
    btn.addEventListener('click', function(){
      // 使用AJAX异步对象发送请求给服务端
      // 1.1 创建一个异步实例对象
      var xhr = new XMLHttpRequest();
      // 1.2 设置请求行   三个参数:  请求方式get/post  请求目标服务器地址  是否异步(默认),ture(异步),false(同步)
      xhr.open('get', "http://127.0.0.1:3001/getData", true);   // 通过getData接口请求服务器的数据
      // 因为这个使用的是get方式请求服务器,可以省略不写,模块会自动生成
      // 1.4 设置请求体
      // 由于是get请求,请求体没有数据,所以写null
      xhr.send(null);
      // 1.5 监听异步对象状态
      xhr.onreadystatechange = function(){
        console.log(xhr.readyState);
        // 一次成功的请求和响应,至少包括两个方面
        // 第一个,将请求发送过去,服务器端接收到响应并做了处理,状态码用200表示
        // 第二个,接受到数据之后,必须保证全部的数据都接收到,而且都对接收到的数据进行完全的解析或处理  状态值为4
        if(xhr.status==200 && xhr.readyState==4){
          console.log(xhr.responseText);  //异步对象的responseText来接收服务器端响应回来的数据
          console.log(typeof xhr.responseText);
          //将字符串对象转换成数组或对象格式
          var obj = JSON.parse(xhr.responseText);
          var data = obj.data;
          for(var i=0; i<data.length; i++){
            // 创建一个元素
            var li = document.createElement('li');
            li.innerHTML = data[i].name;
            // 插入数据
            ul.appendChild(li);
          }
        }
        
      }
    })
  </script>
</body>
</html>

 

效果

 

2. 使用AJAX异步对象发送get请求

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>注册用户名</title>
</head>
<body>
  <form action="/submit" method="get">
    用户名: <input type="text" name="userName" id="userName"><span></span><br />
    密 码: <input type="text" name="userPwd" id="userPwd"><br/>
    <!-- <input type="submit"> -->
    <input type="button" id="btn" value="提交">
  </form>
  <script>
    // http://127.0.0.1:3002/submit?userName=tom&userPwd=123
    // URL地址栏拼接参数的形式给服务器传递数据
    
    // 1. 获取页面中的标签对象
    var btn = document.querySelector('#btn');
    var userNmae = document.querySelector('#userName');
    var userPwd = document.querySelector('#userPwd');

    // 2. 给按钮注册事件
    userName.onblur = function(){
      var val = this.value;
      if(!val.trim()){
        alert("用户名不能为空...");
        return; // 中断代码向下执行
      }
      var xhr = new XMLHttpRequest();
      xhr.open('get', '/validate?userName=' + userName.value);  // validate这个接口是用来判断用户名是否存在的
      //get方式请求可以忽略请求头
      // 设置请求体
      xhr.send(null); // 因为get请求是通过URL地址栏拼接参数的形式传递数据,所以这里没有请求数据,需要写一个null
      // 监视异步对象的状态
      xhr.onreadystatechange = function(){
        if(xhr.status==200 && xhr.readyState==4){
          userName.nextElementSibling.innerHTML = xhr.responseText;
        }
      }
    }

  </script>
</body>
</html>

 

3.使用AJAX异步对象发送POST请求

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>注册用户名</title>
</head>
<body>
  <form>
    用户名: <input type="text" name="userName" id="userName"><span></span><br />
    密 码: <input type="text" name="userPwd" id="userPwd"><br/>
    <!-- <input type="submit"> -->
    <input type="button" id="btn" value="注册">
  </form>
  <script>
    var btn = document.querySelector('#btn');
    var userName = document.querySelector('#userName');
    var userPwd = document.querySelector('#userPwd');
    var val;
    
    userName.onblur = function(){
      val = this.value;
      if(!val.trim()){
        alert("用户名不能为空!");
        return;
      }
      var xhr = new XMLHttpRequest();
      xhr.open('post', '/validate');
      xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

      xhr.send('userName=' + val);
      xhr.onreadystatechange = function(){
        if(xhr.status==200 && xhr.readyState==4){
          console.log(xhr.responseText);
          userName.nextElementSibling.innerHTML = xhr.responseText;
        }
      }
    }
    
    // 点击按钮提交数据
    btn.onclick = function(){
      var xhr = new XMLHttpRequest();
      xhr.open('post', '/submit');
      xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
      var param = {
        "userName": val,
        "userPwd": userPwd.value,
      }
      obj = JSON.stringify(param);
      console.log(obj);
      
      xhr.send(obj);
      console.log(typeof obj);
      
      // console.log('userName=' + val +'&'+ 'userPwd=' + userPwd.value);
      
      xhr.onreadystatechange = function(){
        if(xhr.status===200 && xhr.readyState==4){
          alert("注册成功");
        }
      }
    }
  </script>
</body>
</html>

 

4.服务端代码 app.js

// 1. 引入模块
const http = require('http')
const path = require('path')
const fs = require('fs')
const querystring = require('querystring')
const urlModule = require('url')

// 2. 创建服务器对象
var server = http.createServer()

// 3. 开启服务并监听端口
server.listen(3002,()=>{
  console.log('the server is running at http://127.0.0.1:3002');
})

// 4.注册请求事件,监听请求
server.on('request',(req,res)=>{
  var urlObj = urlModule.parse(req.url,true);
  var pathname = urlObj.pathname;// 获取请求路径
  var method = req.method;
  var query = urlObj.query;
  if(method=='GET'&&pathname=='/index.html'){
    fs.readFile(path.join(__dirname,'views/index.html'),(err,data)=>{
      if(err) return res.end('404')
      res.end(data)
    })  
  }else if (method == 'GET' && pathname == '/register.html') {
    fs.readFile(path.join(__dirname, 'views/register.html'), (err, data) => {
      if (err) return res.end('404')
      res.end(data)
    })
  } else if (method == 'GET' && pathname == '/submit') {
    var userName = query.userName;
    var userPwd = query.userPwd;
    fs.readFile(path.join(__dirname,'data.json'),'utf-8',(err,data)=>{
      if(err) return res.end('404')
      var arr = JSON.parse(data);
      var flag = true;
      arr.some(item=>{
        if(userName == item.userName){
          flag = false;
          return true;
        }
      })
      if(flag){
        arr.push(query);
        fs.writeFile(path.join(__dirname,'data.json'),JSON.stringify(arr,null,' '),err=>{
          res.writeHeader(200, {
            "Content-Type": "text/plain;charset=utf-8",
            "refresh": "3;url=/index.html"
          })
          res.end("恭喜你,注册成功")
        })
        
      }else {
        res.writeHeader(200, {
          "Content-Type": "text/plain;charset=utf-8",
          "refresh": "3;url=/register.html"
        })
        res.end('你好倒霉啊,用户名已经被占用,亲,换一个吧')
      }
    })
  }else if(method=='POST'&&pathname=='/submit'){
    var str = ''
    req.on('data',chunk=>{
      str += chunk;
    })
    req.on('end',()=>{
      var user = querystring.parse(str);// 将post过来的数据转换成对象
      fs.readFile(path.join(__dirname,'data.json'),'utf-8',(err,data)=>{
        if(err) return console.log(err.message);
        var arr = JSON.parse(data)
        var flag = true;
        arr.some(item=>{
          if(item.userName == user.userName){
            flag = false;
            return true;
          }
        })

        if (flag) {
          arr.push(user);
          fs.writeFile(path.join(__dirname, 'data.json'), JSON.stringify(arr,null,' '), err => {
            res.writeHeader(200, {
              "Content-Type": "text/plain;charset=utf-8",
              "refresh": "3;url=/index.html"
            })
            res.end("恭喜你,注册成功")
          })
        } else {
          res.writeHeader(200, {
            "Content-Type": "text/plain;charset=utf-8",
            "refresh": "3;url=/register.html"
          })
          res.end('你好倒霉啊,用户名已经被占用,亲,换一个吧')
        }
      })
    })
  }else if(method=='GET'&&pathname=='/validate'){
    fs.readFile(path.join(__dirname,'data.json'),'utf-8',(err,data)=>{
      if(err) return console.log(err.message);
      var arr = JSON.parse(data);
      var flag = true;
      arr.some(item=>{
        if(query.userName==item.userName){
          flag = false
          return true;
        }
      })
      if(flag){
        res.writeHeader(200,{
          'Content-Type':'text/plain;charset=utf-8'
        })
        res.end('恭喜你,用户名可以使用')
      }else {
        res.writeHeader(200, {
          'Content-Type': 'text/plain;charset=utf-8'
        })
        res.end('抱歉,用户名已经被占用,请更换一个')
      }
    })
  } else if (method == 'POST' && pathname == '/validate'){
    var str = ''
    req.on('data', chunk => {
      str += chunk;
    })
    req.on('end', () => {
      var user = querystring.parse(str);// 将post过来的数据转换成对象
      fs.readFile(path.join(__dirname, 'data.json'), 'utf-8', (err, data) => {
        if (err) return console.log(err.message);
        var arr = JSON.parse(data)
        var flag = true;
        arr.some(item => {
          if (item.userName == user.userName) {
            flag = false;
            return true;
          }
        })

        if (flag) {
         res.writeHeader(200,{
           'Content-Type':'text/plain;charset=utf-8'
         })
            res.end("恭喜你,此用户名可以使用")

        } else {
          res.writeHeader(200, {
            "Content-Type": "text/plain;charset=utf-8"
          })
          res.end('你好倒霉啊,用户名已经被占用,亲,换一个吧')
        }
      })
    })
  }else if(method=='GET'&&pathname=='/getData'){
    fs.readFile(path.join(__dirname,'data.json'),'utf-8',(err,data)=>{
      if(err) return res.end('404')
      res.end(JSON.stringify({
        "code":200,
        "des":"请求成功",
        "data":JSON.parse(data)
      }))
    })
  }else {
    res.end('404')
  }
})

 

5.JSON数据  data.json

[
{
  "userName": "tom",
  "userPwd": "123"
},
{
  "userName": "tom123",
  "userPwd": "123"
},
{
  "userName": "aaa",
  "userPwd": "123"
},
{
  "userName": "rose",
  "userPwd": "123"
}
]
posted @ 2019-05-19 13:54  replaceroot  阅读(123)  评论(0编辑  收藏  举报