【JavaScript】Ajax

1. 前后端交互

web开发分为前端和后端。

  • 前端是面向用户的一端,即浏览器程序开发。
  • 后端则是为前端提供服务,即服务器程序开发。

Node内置有web服务器。

在动态网站中,许多功能是由前后端交互实现的。

  • eg:用户注册和登录、发表评论、查询积分等

前后端操作分为两类:

  • 向服务器提交数据(表单交互)
  • 向服务器查询数据(URL参数交互)

表单交互:

  • 指在HTML中创建一个表单,用户填写表单后提交给服务器,服务器收到表单后返回处理结果。

在这里插入图片描述
URL参数交互:

  • 用于浏览器向服务器提交一些请求信息。
  • 例如:http://localhost:3000/index?username=张三&gender=男

在这里插入图片描述

2. Ajax

2.1 Ajax概述

Ajax:Asynchronous JavaScript And XML,异步JavaScript和XML技术。
在 2005年被Jesse James Garrett提出的新术语,用来描述一种使用现有技术集合的‘新’方法。
包括: HTML 或 XHTML, CSS, JavaScript, DOM, XML, XSLT, 以及最重要的XMLHttpRequest。
使用Ajax技术网页应用能够快速地将增量更新呈现在用户界面上,而不需要重载(刷新)整个页面,这使得程序能够更快地回应用户的操作。

功能: 用于实现与服务器进行异步交互的功能。

  • 不刷新页面更新网页
  • 在页面加载后从服务器请求数据
  • 在页面加载后从服务器接收数据
  • 在后台向服务器发送数据
  • AJAX提供与服务器异步通信的能力,可以在Web页面触发的JavaScript事件中向服务器发出异步请求,执行更新或查询数据库。
  • AJAX的核心是JavaScript对象XMLHttpRequest,该对象在IE 5中首次引入,使用户通过JavaScript向服务器提出请求并处理响应,而不阻塞用户。通过这个对象,您的 JavaScript 可在不重载页面的情况与 Web 服务器交换数据,即在不需要刷新页面的情况下,就可以产生局部刷新的效果。
  • 当Web服务器的响应返回时,使用JavaScript回调函数和CSS来相应地更新页面的局部内容,而不是刷新整个页面。
  • 在页面与服务器交互的过程中不中断用户操作,用户甚至察觉不到浏览器正在与服务器通信
    在这里插入图片描述

优势:

  • 减轻服务器的负担
  • 节省带宽
  • 用户体验更好

2.2 Ajax如何工作

在这里插入图片描述

  1. 网页中发生了一个事件(页面加载、按钮点击)
  2. 由JavaScript创建XMLHttpRequest对象
  3. XMLHttpRequest对象通过open()方法建立对服务器的调用、设置回调函数 、调用send()方法向web服务器发送请求
  4. 服务器处理该请求
  5. 服务器将响应发送回网页
  6. 由JavaScript读取响应
  7. 由JavaScript执行正确的动作(比如更新页面)

2.3 XMLHttpRequest对象

Ajax 的核心是 XMLHttpRequest 对象。

  • 所有现代浏览器都支持 XMLHttpRequest 对象。
  • XMLHttpRequest 对象用于同幕后服务器交换数据。这意味着可以更新网页的部分,而不需要重新加载整个页面。

创建XMLHttpRequest对象:

  1. 所有现代浏览器(Chrom、IE7+、Firefox、Safari 以及 Opera)都有内建的 XMLHttpRequest 对象。创建 XMLHttpRequest 的语法是:variable = new XMLHttpRequest();
  2. 老版本的 Internet Explorer(IE5 和 IE6)使用 ActiveX 对象:variable = new ActiveXObject("Microsoft.XMLHTTP")

注:为了应对所有浏览器,包括 IE5 和 IE6,请检查浏览器是否支持 XMLHttpRequest 对象。如果支持,创建 XMLHttpRequest 对象,如果不支持,则创建 ActiveX 对象:

var xhttp;
if (window.XMLHttpRequest) {
    xhttp = new XMLHttpRequest();
    } else {
    // code for IE6, IE5
     xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}

XMLHttpRequest 对象方法:

  • new XMLHttpRequest():创建新的 XMLHttpRequest 对象
  • abort():取消当前请求
  • getAllResponseHeaders():返回头部信息
  • getResponseHeader():返回特定的头部信息
  • open(method, url, async, user, psw)
    method:请求类型 GET或POST
    url:文件位置
    async:true(异步)或 false(同步)
    user:可选的用户名称
    psw:可选的密码
  • send():将请求发送到服务器,用于 GET 请求
  • send(string):将请求发送到服务器,用于 POST 请求
  • setRequestHeader():向要发送的报头添加标签/值对

XMLHttpRequest 对象属性:

  • onreadystatechange:定义当 readyState 属性发生变化时被调用的函数
  • readyState
    保存 XMLHttpRequest 的状态。
    0:请求未初始化
    1:服务器连接已建立
    2:请求已收到
    3:正在处理请求
    4: 请求已完成且响应已就绪
  • responseText:以字符串返回响应数据
  • responseXML:以 XML 数据返回响应数据
  • status:返回请求的状态号
    200: “OK”
    403: “Forbidden”
    404: “Not Found”
  • statusText:返回状态文本(比如 “OK” 或 “Not Found”)

2.4 使用Ajax

eg: form表单中的值提交到后台 后台存入数据库

ajax底层使用:

<script>
        //获取XMLHTTPRequest对象
        function getXmlHttpRequest(){
            let xmlHttpRequest;
            if(window.ActiveXObject){//若是IE浏览器
                xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
            }else if(window.XMLHttpRequest){//非IE浏览器
                xmlHttpRequest = new XMLHttpRequest();
            }
            return xmlHttpRequest;
        }

        //通过XMLHttpRequest对象向后台发送异步请求
        function getServerInfo() {
            //获取Ajax的核心对象
            let httpRequest = getXmlHttpRequest();
            //获取表单数据
            let name = document.getElementById('emp_name').value;
            let gender = document.getElementById('emp_gender').value;
            let birthday = document.getElementById('emp_birthday').value;
            let phone = document.getElementById('emp_phone').value;
            let address = document.getElementById('emp_address').value;
			
			// 拼接要发送的值
            let post_str = 'emp_name='+name+'&emp_gender='+gender+'&emp_birthday='+birthday+'&emp_phone='+phone+'&emp_address='+address;

            //调用open()方法建立与服务器的连接
            httpRequest.open('post','http://localhost:3000/index',true);

            //设置请求头信息
            httpRequest.setRequestHeader('Content-Type','application/x-www-form-urlencoded');

            //设置请求-响应状态发生改变时的回调函数
            httpRequest.onreadystatechange = function () {
                if(httpRequest.readyState == 4 && httpRequest.status == 200){//请求-响应成功完成
                    //获取响应信息
                    let info = httpRequest.responseText;
                    //将获取到的响应信息写入到页面的span标签中
                    document.getElementById('msg').innerHTML = info;
                }
            }
            //向服务器发送请求
            httpRequest.send(post_str);
        }
    </script>

jquery对ajax的封装:
需要引入jquery库

$.ajax({
    url: '远程服务器的地址',
    type: '请求方式',
    data: '发送给服务器端的数据',
    dataType: '服务器返回的数据的格式',
    success: function(data) {
        //请求成功后的回调函数,参数data中放的是服务器的响应数据
    },
    error: function(err) {
        //请求失败的回调函数,参数"err"中放的是错误信息
    }
})
   <script>
       $(function () {
           $('#btn_ok').click(function () {
               $.ajax({
                   url: 'http://localhost:3000/index',
                   type: 'post',
                   data: $('form').serialize(), //表单序列化:将表单控件的值拼接成字符串
                   dataType: 'json',
                   success: function (result) {
                       $('#msg').html(result.info);
                   }
               })
           });
       })
   </script>

jquery对ajax的高层封装:
需要引入jquery库*

只能进行post请求:
$post(url,[data],[callback],[type])

url:发送请求的地址
data:待发送的key/value参数
callback:发送成功时的回调函数
type:返回的内容格式:xml、html、script、json、text等
let obj = {
	name: 'AAA',
	age: 24,
	gender: '男'
};
$post("http://localhost:3000/index",obj,function(result){'成功后的处理代码'},'json')
只能进行get请求:
$get(url,[data],[callback],[type])

url:发送请求的地址
data:待发送key/value参数
callback:发送成功时的回调函数
type:返回的内容格式:xml、html、script、json、text等

eg:使用ajax实现页面的数据通过Node后台提交到数据库

使用ajax涉及到跨域问题,需要注意

项目结构:
在这里插入图片描述

  • dbconfig.js
//导入mysql模块
const mysql = require('mysql2');

//创建数据库连接对象
const connection = mysql.createConnection({
    host:'localhost',
    port:3306,
    user:'root',
    password:'*****',
    database:'deyun'
})

//让数据库的连接对象对外可见
module.exports = connection;
  • client.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="http://localhost:3000/index" method="post">
        姓名:<input type="text" name="emp_name" id="emp_name"><br><br>
        性别:<input type="text" name="emp_gender" id="emp_gender"><br><br>
        生日:<input type="date" name="emp_birthday" id="emp_birthday"><br><br>
        电话:<input type="text" name="emp_phone" id="emp_phone"><br><br>
        地址:<input type="text" name="emp_address" id="emp_address"><br><br>
        <input type="button" value="提交" onclick="getServerInfo()">
    </form>

    <br><br>
    <span id="msg" style="color:red;font-size:20px"></span>

    <script>
        //获取XMLHTTPRequest对象
        function getXmlHttpRequest(){
            let xmlHttpRequest;
            if(window.ActiveXObject){//若是IE浏览器
                xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
            }else if(window.XMLHttpRequest){//非IE浏览器
                xmlHttpRequest = new XMLHttpRequest();
            }
            return xmlHttpRequest;
        }

        //通过XMLHttpRequest对象向后台发送异步请求
        function getServerInfo() {
            //获取Ajax的核心对象
            let httpRequest = getXmlHttpRequest();
            //获取表单数据
            let name = document.getElementById('emp_name').value;
            let gender = document.getElementById('emp_gender').value;
            let birthday = document.getElementById('emp_birthday').value;
            let phone = document.getElementById('emp_phone').value;
            let address = document.getElementById('emp_address').value;
			
			// 拼接要发送的值
            let post_str = 'emp_name='+name+'&emp_gender='+gender+'&emp_birthday='+birthday+'&emp_phone='+phone+'&emp_address='+address;

            //调用open()方法建立与服务器的连接
            httpRequest.open('post','http://localhost:3000/index',true);

            //设置请求头信息
            httpRequest.setRequestHeader('Content-Type','application/x-www-form-urlencoded');

            //设置请求-响应状态发生改变时的回调函数
            httpRequest.onreadystatechange = function () {
                if(httpRequest.readyState == 4 && httpRequest.status == 200){//请求-响应成功完成
                    //获取响应信息
                    let info = httpRequest.responseText;
                    //将获取到的响应信息写入到页面的span标签中
                    document.getElementById('msg').innerHTML = info;
                }
            }
            //向服务器发送请求
            httpRequest.send(post_str);
        }
    </script>
</body>
</html>

服务器未设置跨域访问出现的问题:

  • httpserver.js

//导入http模块:用户创建http服务器
const http = require('http');

//导入querystring模块:用来解析客户端提交的数据
const queryString = require('querystring');

//导入数据库的配置模块:用于数据库的操作
const connection = require('../db/dbconfig');

//创建http服务器:对应的请求地址是:http://localhost:3000/index
let server = http.createServer((req,res) => {
    //获取客户端请求的地址
    let clientUrl = req.url;
    console.log(clientUrl);
    
    if (clientUrl === '/index'){
        let body = '';//用来保存客户端提交的请求数据
        //给请求对象req绑定'data'事件:用来获取客户端的请求数据
        req.on('data',chunk => {
            body += chunk;
        });
        
        //给请求对象req绑定'end'事件
        req.on('end',() => {
            let params = queryString.parse(body);//将body中的数据转换为键值对的形式
           
            res.setHeader("Content-Type", "application/json;charset=utf-8");
            
            //拼接响应字符串
            let res_str = '姓名:'+params.emp_name+"\n"+
                          '性别:'+params.emp_gender+"\n"+
                          '生日:'+params.emp_birthday+"\n"+
                          '电话:'+params.emp_phone+'\n'+
                          '地址:'+params.emp_address;
            console.log(res_str);
            
            //将响应字符串发送给客户端  先把信息写入数据库,再响应给客户端
            save(params);
            res.write('插入数据成功!');
            
            //关闭连接
            res.end();
        })
    }
})
server.listen(3000);//绑定端口号

//创建将数据保存到数据库的方法
function save(params){
    connection.query('insert into employee set ?',{
        name:params.emp_name,
        gender:params.emp_gender,
        birthday:params.emp_birthday,
        phone:params.emp_phone,
        address:params.emp_address
    },(err,result) => {
        if(err){
            console.log(err);
            return;
        }
        console.log('插入数据成功');
        connection.end();//断开数据库的连接
    })
}

在这里插入图片描述

服务器设置跨域访问:


//导入http模块:用户创建http服务器
const http = require('http');

//导入querystring模块:用来解析客户端提交的数据
const queryString = require('querystring');

//导入数据库的配置模块:用于数据库的操作
const connection = require('../db/dbconfig');

//创建http服务器:对应的请求地址是:http://localhost:3000/index
let server = http.createServer((req,res) => {
    //获取客户端请求的地址
    let clientUrl = req.url;
    console.log(clientUrl);

    if (clientUrl === '/index'){
        let body = '';//用来保存客户端提交的请求数据
        //给请求对象req绑定'data'事件:用来获取客户端的请求数据
        req.on('data',chunk => {
            body += chunk;
        });

        //给请求对象req绑定'end'事件
        req.on('end',() => {
            let params = queryString.parse(body);//将body中的数据转换为键值对的形式

            //设置服务器端的响应头信息,实现跨域
            res.setHeader("Access-Control-Allow-Origin", "*");
            res.setHeader("Access-Control-Allow-Headers", "Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild");
            res.setHeader("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
            res.setHeader("X-Powered-By","3.2.1");
            res.setHeader("Content-Type", "application/json;charset=utf-8");


            //拼接响应字符串
            let res_str = '姓名:'+params.emp_name+"\n"+
                          '性别:'+params.emp_gender+"\n"+
                          '生日:'+params.emp_birthday+"\n"+
                          '电话:'+params.emp_phone+'\n'+
                          '地址:'+params.emp_address;
            console.log(res_str);

            //将响应字符串发送给客户端  先把信息写入数据库,再响应给客户端
            save(params);
            res.write('插入数据成功!');

            //关闭连接
            res.end();
        })
    }
})
server.listen(3000);//绑定端口号

//创建将数据保存到数据库的方法
function save(params){
    connection.query('insert into employee set ?',{
        name:params.emp_name,
        gender:params.emp_gender,
        birthday:params.emp_birthday,
        phone:params.emp_phone,
        address:params.emp_address
    },(err,result) => {
        if(err){
            console.log(err);
            return;
        }
        console.log('插入数据成功');
        connection.end();//断开数据库的连接
    })
}
```![在这里插入图片描述](https://img-blog.csdnimg.cn/d21b49d67690454da974b26ae3b6cfa3.gif#pic_center)


  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南栀~zmt

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值