Ajax基础知识 · 下

Ajax的应用场景:

1、页面上拉加载更多数据

2、列表数据无刷新分页

3、表单项离开焦点数据验证

4、搜素框提示文字下拉列表

Ajax运行原理

Ajax基础知识 · 下_第1张图片

服务器端响应的数据格式:在http请求与响应的过程中,无论是请求参数还是响应内容,如果是对象类型,最终都会被转换为对象字符串进行传输(这是规定)

浏览器端还需要把服务器端响应的json字符串转换为json对象

/*  在http请求与响应的过程中,无论是请求参数还是响应内容,如果是对象类型,最终都会被转换为对象字符串进行传输(这是规定)
    客户端还需要把服务器端响应的json字符串转换为json对象 */
        var responseText = JSON.parse(xhr.responseText)

请求报文:在Http请求和响应的过程中传递的数据块就叫报文,包括要传送的数据和一些附加信息,这些数据和信息要遵守规则和定好的格式

请求参数的格式

1、application/x-www-form-urlencoded

name=zhangsan&age=20&sex=

2、application/json

{name:'zhangsan',age:'20',sex:'男'}

在请求头中指定Content-Type属性的值是application/json,告诉服务器当前请求参数的格式是json

JSON.stringify() //将json对象转换为json字符串

注意:get请求是不能提交json对象数据格式的,传统网站的表单也是不支持json对象数据格式的

请求类型:分为get请求和post请求

Get请求:参数在URL后面,多个参数用&进行连接

Post请求:参数在请求体中

Ajax状态码

xhr.readyState // 获取Ajax状态码

0:请求未初始化(还没有调用open())

1:请求已经建立,但是还没有发送(还没有调用send())

2:请求已经发送

3:请求正在处理中,通常响应中已经有部分数据可以用了

4:响应已经完成,可以获取并使用服务器的响应了

http常见的状态码:

xhr.status // 获取http常见的状态码

200:表示响应成功

404:没有找到请求的资源

500:服务器端错误

同源政策

同源:协议,域名,端口这三者条件必须相同

为什么会有同源政策?

——为了保证用户信息的安全,防止恶意的网站窃取数据。

同源政策是浏览器给予Ajax技术的限制,服务器端是不存在同源政策限制。

Ajax请求限制:Ajax只能向自己的服务器发送请求。

解决跨域问题

Ajax是为了访问自己服务器的数据,跨域是为了访问别人服务器的数据

1、CORS 跨域资源共享/非同源资源共享,它允许浏览器向跨域服务器发送Ajax请求,克服了Ajax只能同源使用的限制

Ajax基础知识 · 下_第2张图片

2、使用JSONP解决同源限制问题,它不属于Ajax请求,但是它可以模拟Ajax请求

jsonp的原理与实现

(1)首先是利用script标签的src属性来实现跨域。

<body>
    <script>
        // 2、定义函数
        function fun(data) {
            console.log('客户端的fun函数被调用')
            console.log(data)
        }
    </script>
    
    <!-- 1、将非同源服务器端的请求地址写在script标签的src里面 -->
    <!-- 把函数名传递给服务器 -->
    <script src="http://localhost:3001/test?callback=fun"></script>
</body>

(2)通过将前端方法作为参数传递到服务器端,然后由服务器端注入参数之后再返回,实现服务器端向客户端通信。

app.get('/test', (req, res) => {
    const name = req.query.callback
    const result = name + '({name:"zhangsan"})'
    res.send(result)
})

(3)由于使用script标签的src属性,因此只支持get方法

3、服务器进行跨域,浏览器吧请求发送给自己的服务器,之后自己的服务器去访问其他的服务器数据,再返回给浏览器,绕过了浏览器的同源策略

// 客户端访问自己服务器 s1
 <script src="./js/ajax.js"></script>
    <script>
        // 获取按钮元素
        var btn = document.getElementById('btn')
        btn.onclick = function() {
            ajax({
                url: 'http://localhost:3000/server',
                type: 'get',
                success: function(result) {
                    console.log(result)
                }
            })
        }
    </script
// s1 服务器访问s2服务器
// 对应s1中 06html文件
app.get('/server', (req, res) => {
    // 访问s2的服务器,需要借助第三方模块 request
    request('http://localhost:3001/cors', (err, response, body) => {
        res.send(body)
    })
})

JSONP与CORS区别

实际上,cors和jsonp都是用于解决跨域问题,当两个页面的协议、域名、端口号中有一个不一致时就存在了跨域,一旦出现跨域,浏览器发送跨域请求后,请求回来的数据都会被浏览器所拦截。

Ajax基础知识 · 下_第3张图片

JSONP的原理是动态创建script标签

1.JSONP发送的不是ajax请求

2.JSONP不支持post请求

3.JSONP没有兼容问题

CORS中文意思是跨域资源共享,需要在服务器端设置cops配置

1.CORS发送的是真正的ajax请求

2.CORS既支持get 又支持post

3.有兼容问题,只有ie10及以上才支持

withCredentials

withCredentials:指定在涉及到跨域请求时,是否携带cookie信息,默认值为false。

在使用Ajax技术发送跨域请求时,默认情况下不会在请求中携带cookie信息。

// 在服务器中添加这样一句话
// 允许客户端发送跨域请求时携带cookie信息
  res.header('Access-Control-Allow-Credentials', true)
//下拉框改变事件 
province.onchange = function() {}

//用户输入事件
 user.oninput=function(){}

防抖与节流知识点

防抖:指在事件触发n秒后再执行回调,如果在n秒内再次被触发,则重新计算时间。比如说,我点击屏幕,八秒后出现结果,但是我在八秒内又点击屏幕,之后又要等八秒才有结果,我一直点就会一直重新等八秒,直到我最后一次点,等八秒就有结果。

主要应用场景有

a、scroll事件滚动触发,

b、搜索框输入查询

c、表单验证

d、按钮提交事件

e、浏览器窗口缩放,resize事件

节流:如果持续触发某个事件,则每隔n秒执行一次。比如,我点击屏幕,八秒显示结果,我点第一次,点第二次,点第三次……,等八秒出现点击第一次的结果,之后又出现第二次的结果,……有点点像卡顿的那种,你每次的点击,都会等八秒才给你响应。

主要应用场景

a、DOM元素的拖拽功能实现

b、射击游戏类

c、计算鼠标移动的距离

d、监听scroll事件

key.trim() //内容去空格

FormData对象的作用

1.模拟HTML表单,相当于将HTML表单映射成表单对象,自动将表单对象中的数据拼接成请求参数的格式。

// 客户端
<script>
        // 获取提交按钮
        var btn = document.getElementById('btn')
            // 获取表单
        var form = document.getElementById('form')
        btn.onclick = function() {
            // 将普通表单转化为FormData表单
            // formData只能使用post请求发送 
            var formData = new FormData(form)

            // 使用ajax发送数据
            // 1、创建ajax
            var xhr = new XMLHttpRequest();
            // 2、发送请求发送和地址
            xhr.open('post', "http://localhost:3000/formData")
                // 3、发送
            xhr.send(formData)
                // 4、监听xhr对象事件
            xhr.onload = function() {
                if (xhr.status == 200) {
                    console.log(xhr.responseText);
                }
            }

        }
    </script>
// 服务端
app.post('/formData', (req, res) => {
    // 创建一个formdata表单解析对象
    const from = new formidable.IncomingForm();
    // 解析客户端传过来的formData对象
    from.parse(req, (err, fields, files) => {
        res.send(fields)
    })
})

2.异步上传二进制文件

// 客户端
<body>
    <div class="container">
        <div class="from-group">
            <label> 请选择文件</label>
            <input type="file" id="file">

            <!-- 显示图片 -->
            <div class="padding" id="imgBox"></div>

            <!-- 进度条 -->
            <div class="progress">
                <div class="progress-bar" style="width:0%" id="bar">0%</div>
            </div>
        </div>
    </div>
    <script>
        // 获取文件内容
        var file = document.getElementById('file');
        // 为文件选择控制添加 onchange 事件
        // 在用户选择文件时触发
        file.onchange = function() {
            // 创建一个formData表单对象
            var formData = new FormData();

            // 获取进度条元素
            var bar = document.getElementById('bar')

            // 获取图片容器
            var imgBox = document.getElementById('imgBox')

            // 把获取的文件追加到formData对象中区
            // 第二个参数是文件files,但我们就选择一个文件,所以是this.files[0],不管选了多少个文件,files都是一个集合,要注意写法
            formData.append('attrName', this.files[0])

            // 创建ajax对象
            var xhr = new XMLHttpRequest()
                // 对ajax对象进行配置
            xhr.open('post', 'http://localhost:3000/upload')

            // 文件上传过程中持续触发
            xhr.upload.onprogress = function(ev) {
                // ev.loaded 文件已经上传了多少
                // ev.total 上传文件的总大小
                var results = (ev.loaded / ev.total) * 100 + '%';
                // 把进度结果发到进度条内容中
                bar.style.width = results;
                bar.innerHTML = results;
            }

            // 发送ajax对象
            xhr.send(formData);
            // 监听服务器端响应给客户端的数据
            xhr.onload = function() {
                if (xhr.status == 200) {
                    // 将服务器端返回的JSON字符串转换为JSON对象
                    var result = JSON.parse(xhr.responseText)
                        // 动态创建img标签
                    var img = document.createElement('img')
                        // 给图片标签设置src属性
                    img.src = result.path;
                    // 当图片加载完成以后
                    img.onload = function() {
                        // 将图片显示在页面中
                        imgBox.appendChild(img)
                    }

                }
            }

        }
    </script>
</body>
// 服务端
app.post('/upload', (req, res) => {
    // 创建一个formdata表单解析对象,设置保留文件后缀名
    const form = new formidable.IncomingForm({ keepExtensions: true });
    // 设置客户端上传文件的存储路径
    form.uploadDir = path.join(__dirname, 'public', 'uploads');
    // 解析客户端传过来的formData对象
    form.parse(req, (err, fields, files) => {
        // 服务器要把图片地址返回给客户端
        res.send({
            path: files.attrName.filepath.split('public')[1]
        })
    })
})

FormData对象只能使用post请求方式

FormData对象的属性

// 获取表单对象的值
formData.get('key');//key是name属性的值

// 设置表单对象中属性的值
// 如果设置的表单属性不存在,则会创建这个表单属性,如果存在则会覆盖
formData.set('key','value');

// 删除表单对象中属性的值
formData.delete('key');

// 向表单对象中追加属性值
formData.append('key','value')
// 例如:创建空的表单对象
var f = new FormData();
f.append('sex','男');
console.log(f.get('sex'));

注意: set方法与append 方法的区别是,在属性名已存在的情况下,set会覆盖已有键名的值,append会保留两个值。

Jquery中 $.ajax()

作用:发送Ajax请求

 <script src="./js/jquery.min.js"></script>
  <script>
        // 使用jquery
        $('#btn').on('click', function() {
            // 使用jQuery中的ajax
            $.ajax({
                //请求方式
                type: 'post',
                // 请求地址 
                // 如果访问自己的服务器,可以省去协议,域名,端口
                url: '/user',
                data: {
                    name: 'lisi',
                    age: '18',
                },
                // 在请求发送之前调用
                beforeSend: function() {
                    alert('请求不会被发送')
                        // 请求不会被发送
                    return false
                },
                // 指定参数的格式类型 
                contentType: 'application/json',
                // 请求成功以后函数被调用
                success: function(response) {
                    // response为服务器端返回的数据
                    // 方法内部会自动将json字符串转换为json对象
                    console.log(response)
                },
                // 请求失败以后函数被调用
                error: function(xhr) {
                    console.log(xhr)
                }
            })
        })
    </script>

serialize方法

作用:将表单中的数据自动拼接成字符串的参数

<script type="text/javascript">
        // 提交事件
        $('#form').on('submit', function() {
            // 将表单内容拼接成字符串类型的参数
            var param = $('#form').serialize()
            console.log(param)
            return false
        })
    </script>

$.ajax方法发送jsonp请求

// 客户端
<script src="./js/jquery.min.js"></script>
    <script>
        $('#btn').on('click', function() {
            $.ajax({
                url: '/jsonp',
                // 指定当前发送jsonp请求
                dataType: 'jsonp',
                // 修改callback参数名称
                // jsonp: 'cb',
                // 指定函数名称 ,如果你不想要success这个函数,你可以通过这个自己创一个函数,要提前先定义好函数
                // jsonpCallback: 'fnName',
                success: function(response) {
                    console.log(response)
                }
            })
        })
    </script>
    
    
// 服务端
app.get('/jsonp', (req, res) => {
    res.jsonp({
        name: 'xuxi',
        age: 18,
    })
})

$.get() 和 $.post()

作用:$.get() 方法用于发送get方法; $.post() 方法用于发送post方法

// 客户端
<script>
        $('#btn').on('click', function() {
            // $.get('/base', {
            //     name: 'zhangsan',
            //     age: '18'
            // }, function(response) {
            //     console.log(response)
            // })

            $.post('/base', function(response) {
                console.log(response)
            })
        })
    </script>
    
    
// 服务器端
app.get('/base', (req, res) => {
    res.send(req.query)
})
app.post('/base', (req, res) => {
    res.send({ name: 'xuxi' })
})

jquery中Ajax全局事件 ajaxStart,ajaxComplete

只要页面中有ajax请求被发送,对应的全局事件就会被触发

// 当页面中有ajax请求发送时触发
$(document).on('ajaxStart',function(){
    console.log('start');
})

// 当页面中有ajax请求完成时触发
$(document).on('ajaxComplete',function(){
    console.log('complete');
}))

NProgress 插件,使用逼真的涓流动画来告诉用户正在发生的事情。

// 1.引入插件的css文件

// 2.引入插件的js文件

// 3.开始调用
// 当页面中有ajax请求发送时触发
$(document).on('ajaxStart',function(){
   NProgress.start()
})

// 当页面中有ajax请求完成时触发
$(document).on('ajaxComplete',function(){
    NProgress.done()
}))
**邮箱验证规则**/^[A-Za-z\d]+([-_ .][A-Za-z\d]+)*@([A-Za-z\d]+[-.])+[A-Za-z\d]{2,4}$/

你可能感兴趣的:(学习笔记,前端,ajax,node.js)