数据交互—ajax

1.Ajax

ajax全称 “Asynchronous Javascript And XML”,即“异步JavaScript和XML”,就是用JavaScript执行异步网络请求;使用ajax能在不更新整个页面的前提下维护数据
例如:javaweb书城里的注册登录提示用户账号密码是否正确、百度搜索框

ajax不是一个新的编程语言,而是一种使用现有标准实现的新方法

它是一个与服务器交互数据并且更新局部页面的技术,不需要刷新加载整个页面就能实现页面的局部更新

在ajax中xml(可扩展标记语言)就是一种数据格式,用于前后端传输数据的时候使用,现如今已经被json数据格式替代

原理:通过XHR(XMLHttpRequest)对象来向服务器发起异步请求,从服务器获得数据,然后用JS来操作DOM更新页面

Ajax的缺点:

  • 本身是针对MVC的编程,不符合现在前端MVVM浪潮
  • 基于原生的XHR开发,XHR本身的架构不清晰
  • 有回调地狱问题
  • 在使用XHR发起异步请求时得到的是XML格式的数据,如果想要JSON格式,需要额外进行转换(JSON.stringify(data))
  • 配置和调用方式非常混乱,而且基于事件的异步模式不友好

MVVM(Model-View-ViewModel), 源自于经典的 Model–View–Controller(MVC)模式。MVVM 的出现促进了 GUI 前端开发与后端业务逻辑的分离,极大地提高了前端开发效率。MVVM 的核心是 ViewModel 层,它就像是一个中转站(value converter),负责转换 Model 中的数据对象来让数据变得更容易管理和使用,该层向上与视图层进行双向数据绑定,向下与 Model 层通过接口请求进行数据交互,起呈上启下作用。View 层展现的不是 Model 层的数据,而是 ViewModel 的数据,由 ViewModel 负责与 Model 层交互,这就完全解耦了 View 层和 Model 层,这个解耦是至关重要的,它是前后端分离方案实施的最重要一环。

2.认识http协议

http协议也叫超文本传输协议 规定了浏览器与服务器之间的通信规则

请求报文
一个完整的请求组成部分

请求行
以一个符号开头,以空格分开后面跟着url和协议版本

协议版本格式:

Method表示请求方式

  • get 一般用于获取服务器的资源
  • post 一般用于向服务器发送数据
  • head、put、delete…

Request-URL 表示统一资源占位符 协议、端口、域名、资源路径、参数信息

HTTP-Version 表示http的版本号

CRLF 表示回车和换行

请求头

详细信息搜索 MDN HTML headers
Accept 表示客户端接受什么类型的响应
cookie 浏览器的缓存信息
User-Agent 浏览器相关信息
Content-Type 表示需要处理的数据格式(告诉后端我发送的数据格式)

请求体

也叫报文体,就是向后端发送的数据,一共就两种格式,一种是通过表单格式key=value&key2=value2,第二种就是json格式发送

响应报文:响应行、响应头(限制接受到的请求头信息)、响应体(后端返回的数据)

3.XML原生Ajax(get请求)

//1.创建xml对象
let xml = new XMLHttpRequest()
//2.决定请求的方式(设置请求行)
/*
	xml.open(method,url,boolean)
	method 请求方式 get post
	url 请求的地址
	boolean 是否是异步请求,默认是true表示异步请求
*/
/*
	get请求的参数统一都在地址栏拼接的形式发送
*/
xml.open('get','http://139.129.231.168:33344/xmlget?name=xuxing&age=18')
//这里请求的地址是自己在serve.js中写的接口

//3.发起请求,并且发送数据
//xml.send(data)  // data 需要携带的参数(响应体)只可能存在两种格式,一种是key=value 另一种是json字符串
xml.send()

//4.设置请求头
//xml.setResquestHeader('key','value')

//5.获取响应体的内容 - 接受请求到的数据
xml.onreadystatechange = function(){
	// 监听响应状态发生改变时候触发
	console.log(xml.readyState) //表示xml对象的响应阶段
	/*
		返回值为一个数值
		0 表示初始化完成
		1 表示配置信息完成
		2 表示send方法已经执行完成
		3 表示正在解析响应的内容
		4 表示响应内容解析完毕,可以在在客户端进行使用
	*/
	console.log(xml.status) //表示服务端的响应状态码
	/*
		常见的状态码 200 404 403 500
		200 表示响应成功
	*/

	// 当数据处理好以后在获取数据
	if(xml.readyState === 4 && xml.status == 200){
		// 数据已经处理完成并且请求已经被受理
        // 获取响应体
        console.log(xml.response)
        // 以文本的形式获取响应体内容
        console.log(xml.responseText);
        
        document.body.innerHTML += xml.response
	}
}

4.XML原生Ajax(post请求)

// 1.创建 xml 对象 
            let xml = new XMLHttpRequest()

            // 2.决定请求的方式(设置请求行)

            xml.open('post', 'http://139.129.231.168:3344/xmlpost')

            // 4.设置请求头
            // xml.setRequestHeader('Content-Type','application/x-www-form-urlencoded') //表单格式请求头
            xml.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded') //json格式请求头


            // 3.发起请求,并且发送数据
            // xml.send(data)  // data 需要携带的参数(响应体) 只可能存在两种格式,一种是key=value 另一种是json字符串

            /* 
                post 发送数据必须在send函数内发送,参数必须是字符串,字符串有两种格式可以发送
                1.'key=value&key=value' 表单格式对应的请求头 application/x-www-form-urlencoded
                2. '{key:value;key:value}' json格式对应的请求头
            */
            xml.send('name=xuxing&age=18') // 表单格式发送的数据

            let data = {
                name : 'xuxing',
                age : 18
            }
            xml.send(JSON.stringify(data)) 
            

            // 5.获取响应体的内容 - 接受请求到的数据
            xml.onreadystatechange = function () {
                

                // 当数据处理好以后在获取数据
                if (xml.readyState === 4 && xml.status == 200) {
                    
                    console.log(xml.response)
                    // console.log(xml.statusText) //ok 请求的状态
                }
            }

5.xml完整示例

// 1.创建xml
        let xml = new XMLHttpRequest() //终止请求,共享xml,需要放到外面
        send.onclick = function () {
            // 单击按钮发送请求

            // 2.决定请求
            xml.open(post, 'http://127.0.0.1:3344/sendload')
            // 3.配置请求头
            xml.setRequestHeader('Content-Type', 'application/json')
            // 4.发送请求
            let data = {
                name: 'xuxing',
                age: 18
            }

            // 超时限制 当它超过某个时间没有得到结果以后就终止请求
            xml.timeout = 1000
            
            // 超时限制触发以后的回调函数
            xml.ontimeout = function(){
                h1.innerHTML = '你的网络太卡了'
            }

            // 网络异常或后端发生异常的回调函数
            xml.onerror = function(){
                h1.innerHTML = '请求发生了错误'
            }

            // 将后端发送的json 数据处理为普通对象或js数据
            xml.responseType = 'json'

            xml.send(JSON.stringify(data))
            // 5.处理响应的数据 监听响应阶段变化
            xml.onreadystatechange = function () {
                // 当数据处理完成,并且请求已经被受理时获取数据
                if (xml.readyState == 4 && xml.status == 200) {
                    // let data = JSON.parse(xml.response) //将后端返回的JSON字符串序列化成对象
                    h1.innerHTML = data.txt
                }
            }
        }

        abort.onclick = function(){
            // 终止请求
            xml.abort()
        }

6.原生ajax

'use strict'
        /* 
            封装ajax
            request(obj)

            obj 参数值需要是一个对象
            对象内的 method 对应请求方式
            url请求地址
            success 表示请求成功的回调函数
            data 请求携带的参数
        */

        function request(obj) { //设置参数默认值
            // 参数的处理
            let {method='get',url,success=function(){},data={}} = obj


            // 进行请求
            const xml = new XMLHttpRequest()

            // 将传输的数据处理为 key=value 的形式
            let paramStr = Object.entries(data).map(([key, value]) => {  //Object.entries以键值对的形式拿到data里面的值,map遍历把data的值拿出来,[key,value]解构赋值
                return key + '=' + value //trim去除空格,必须是字符串
            }).join('&')  //中间用&拼接
            /* 
            也可以简写为let paramStr = Object.entries(data).map(([key, value]) => return key + '=' + value
            */
            // 判断用户的请求方式
            // method也有可能会是大写GET,所以用toLocaleLowerCase转为小写
            if (method.toLocaleLowerCase() === 'get') {
                // get请求 http://www.baidu.com?key=value&key=value
                xml.open(method, url + '?' + paramStr)

                xml.send()

                xml.onreadystatechange = function () {
                    if (xml.readyState == 4 && xml.status == 200) {
                        console.log(xml.response)
                    }
                }
            }

            //不能使用if...else,不止有这两种请求
            if (method.toLocaleLowerCase() === 'post') {
                // post请求
                xml.open(method, url)

                // 必须设置请求头
                xml.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
                xml.send(paramStr)

                xml.onreadystatechange = function () {
                    if (xml.readyState == 4 && xml.status == 200) {
                        console.log(xml.response)
                    }
                }
            }
        }

        // request('get', 'http://127.0.0.1:3344/xmlget', {
        //     name: 'xuxing',
        //     age: 18
        // }, {
        //     function(data) {
        //         console.log(data)
        //         // 进行数据渲染
        //     }
        // })

        // request('POST', 'http://127.0.0.1:3344/xmlpost', {
        //     name: 'xuxing',
        //     age: 18
        // }, {
        //     function(data) {
        //         console.log(data)
        //         // 进行数据渲染
        //     }
        // })

        request({
            method : 'post',
            url : 'http://127.0.0.1:3344/xmlpost',
            data : {
                name : 'xuxing',
                age : 99
            },
            success(data){
                console.log(data)
            }
        })

7.jQuery-ajax

jQuery ajax是对原生XHR的封装,除此以外还增添了对JSONP的支持

<!-- 引用jquery -->
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/1.6.1/jquery.js"></script>
    <script>
        'use strict'
        /* 
            https://bootcdn.cn/ 开源库查询工具
        */

        // get 请求
        /* 

            $.get(url,data,callback,responseType可选值:text/json) //响应类型
        */
        $('#jqget').click(function () {

            $.get('http://127.0.0.1:3344/jq-ajax', { name: 'afei' }, function (data) {

                console.log(JSON.parse(data)) //若为json,则直接打印data,不需要JSON类型转换
            }) //请求的地址(自己封装的服务器)
        })

        // post 请求
        $('#jqpost').click(function () {

            $.post('http://127.0.0.1:3344/jq-ajax', { name: 'xuxing' }, function (data) {

                console.log(JSON.parse(data))
            }) //请求的地址(自己封装的服务器)
        })

        // 通用版jqall
        $('#jqall').click(function () {

            $.ajax({
                //请求配置信息
                type : 'post', //type或method都可以
                url : 'http://127.0.0.1:3344/jq-ajax',
                data : {
                    name : 'xuxing'
                },
                dataType : JSON,
                success(data){
                    console.log(data)
                },
                err(err){
                    console.log(err)
                },
                headers : {
                    xixixi : 'adfja' //请求头不能为中文
                } //也可以不写
            })
        })



    </script>

7.fetch

fetch 和 axios
两者都是通过es6的promise 方案封装出来的版本,不需要使用回调函数去接受后端响应的数据

fetch 是原生js自带的一个新的api,所有主流浏览器都支持,不需要额外的引用

fetchget.onclick = function () {
            /* 
                fetch(url,settings)
                url 请求的地址
                settings 配置信息
                    method 请求方式
                    headers 请求头信息{}
                    body 请求体内容(需要发送的数据) = {}

                fetch 返回值是一个promise对象获取数据在后续的.then中获取
                错误获取在catch中捕获

            */

            fetch('http://127.0.0.1:3344/jq-ajax', {
                method: 'get',
                // body : 'name:xuxing',
                headers: {
                    xixixi: 'haha'
                }
            }).then(res => {
                // res返回的是一整个响应体,想要拿到数据需要调用内部的方法进行处理
                // test() 方法 会将数据以字符串的形式处理并接受 返回值是一个promise
                // json() 将数据以json格式处理并接受
                return res.json().then(data => {
                    console.log(data)
                })
            })
        }


        fetchpost.onclick = function () {

            fetch('http://127.0.0.1:3344/jq-ajax', {
                method: 'post',
                body: {
                    name: 'afei'
                },
                headers: {
                    xixixi: 'haha'
                }
            }).then(res => {
                // res返回的是一整个响应体,想要拿到数据需要调用内部的方法进行处理
                // test() 方法 会将数据以字符串的形式处理并接受 返回值是一个promise
                // json() 将数据以json格式处理并接受
                return res.json()
            }).then(data => {
                console.log(data)
            })
        }

        /* 
            fetch 使用的场景比较少,因为它一些细节处理的不好比如 他会把 400/500的状态码认为是成功请求来处理,fetch请求默认是不会携带 cookie 信息的,并且不支持超时限制
        */


8.axios

axios是一个基于Promise用于浏览器和nodejs的HTTP客户端,本质上也是对原生XHR的封装,只不过它是Promise的实现版本,符合最新的ES规范
axios的特点

  • 由浏览器端发起请求,在浏览器中创建XHR
  • 支持promise API
  • 监听请求和返回
  • 更好的格式化,自动将数据转化为JSON数据
  • 安全性更高,客户端支持防止CSRF

防止CSRF:就是让你的每个请求都带一个从cookie中拿到的key,根据浏览器同源策略,假冒的网站是拿不到你cookie中的key的,这样,后台就可以轻松辨别出这个请求是否是用户在假冒网站上的误导输入,从而采取正确的策略

<!-- 引入axios -->
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.27.2/axios.min.js"></script>
    <script>
        /* 
                axios   是一个需要外部引用的包
                跟 fetch类似都是通过promise 封装出来的版本,他是一个可以应用与服务端中的ajax请求
            */

        // get
        axiosget.onclick = function () {
            axios.get('http://127.0.0.1:3344/jq-ajax', {
                params: {
                    name: 'xuxing'
                }, headers: {
                    xixix: 'hahah'
                }
            })
                .then(data => {
                    // data 是一个响应体完整信息,具体的内容在 data.data中
                    console.log(data.data)
                })
        }

        // post
        axiospost.onclick = function () {
            axios.post('http://127.0.0.1:3344/jq-ajax', {
                params: {
                    name: 'afei'
                }
            })
                .then(data => {
                    // data 是一个响应体完整信息,具体的内容在 data.data中
                    console.log(data.data)
                })
        }

        // all
        axiosall.onclick = function () {
            axios({
                method: 'post',
                url: 'http://127.0.0.1:3344/jq-ajax',
                headers: {
                    'xixi': 'hahah',
                    'Content-Type': 'application/json'
                },
                data: {
                    name: 'afei',
                    age: 18
                }                   
            }).then(({ data }) => {
                // data 是一个响应体完整信息,具体的内容在 data.data中
                console.log(data)
            })
        }


    </script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

雷旭4466

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

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

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

打赏作者

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

抵扣说明:

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

余额充值