- 0.express基本使用
- 0. 浏览器地址栏输入url后经历:
- 1.AJAX简介:
- 2.XML简介:
- 3.AJAX的特点
- 4.HTML页面是一个响应体
- 5.HTTP(hypertext transport protocol)协议(超文本传输协议)
- 6.post请求和get请求的异同:
- 7.用浏览器查看请求和响应数据
- 8.状态码:
- 9. udp(用户数据报协议面向传输层)和tcp的区别:
- 10.get请求参数设置和post请求体(get没有请求体)
- 11.请求头设置 //设置请求头(身份校验信息放在头信息里面)
- 12.自定义请求头设置 //自定义请求头
- 13.服务器端响应json数据
- 14.解决IE缓存问题:
- 15.解决网络超时或者异常:
- 16.取消请求(abort())
- 17.解决请求重复发送(节流阀)
- 18.jQuery通用方法发送AJAX
- 19.jQuery发送AJAX
- 20.axios通用方法发送AJAX(前端最热门的ajax请求工具包)
- 21.axios发送AJAX
- 22.fetch发送AJAX
- 23.jsonp解决跨域问题
- 24.原生jsonp实践
- 25.jQuery发送jsonp请求
- 26.CORS响应头实现跨域
- 27.原生ajax请求最终代码
- 28. ajax、axios、fetch的区别
- 函数防抖
- 手写节流函数
0.express基本使用
//express服务器框架:基于node.js平台(用于ajax给服务端发请求)
//1.最外层文件下右键在集成终端中打开
//2.安装express包 npm init —yes(npm是node.js平台下的包管理工具) 3.安装express框架npm i express
//4.最后启动服务 右键终端打开 node +tab
//5.浏览器 localhost:8080
//停掉服务CTRL+c
//安装nodemon(npm install -g nodemon)(帮助我们自动重启服务 当文件内容修改时 经常修改服务端代码 经常重启很麻烦)
//启动端口npx nodemon +tab
其他安装:安装axios发送请求,安装babel对(ES5以上)代码进行转换(ES5)+打包
使用json-server 服务端(帮助我们自动搭建http服务)
1.下载: npm install -g json-server
2.目标根目录下创建数据库 json 文件: db.json
{
“posts”: [
{ “id”: 1, “title”: “json-server”, “author”: “typicode” },
{ “id”: 2, “title”: “json-server2”, “author”: “typicode” }
],
“comments”: [
{ “id”: 1, “body”: “some comment”, “postId”: 1 }
],
“profile”: { “name”: “typicode” }
}
3.启动服务器执行命令: json-server —watch db.json(在db.json所在文件夹的集成终端下执行 报错时用管理员方式打开vscode)
//1.引入express
const { response } = require(‘express’)
const express = require(‘express’)
const { request } = require(‘http’)
//2.创建引用对象
const app = express()
//3.创建路由规则
//request对请求报文的封装
//response对响应报文的封装
app.get(‘/‘,(request,response) =>{
response.send(‘hello-3 express’)
})
//4.监听端口启动服务
app.listen(8080,() =>{
console.log(‘服务已经启动,8080,端口监听中’)
})
0. 浏览器地址栏输入url后经历:
1、输入URL;2、浏览器查找是否有缓存,比较缓存是否过期;3、DNS解析域名为ip;4、通过ip简历tcp连接;5、发送http请求;6、服务器处理请求,浏览器接受响应 7、页面构建dom树并进行渲染 8、关闭tcp连接
1.AJAX简介:
AJAX全称Asynchronous JavaScript And XML,就是异步的JS和XML
通过AJAX可以在浏览器中向服务器发送异步请求,
最大的优势:无刷新获取数据 ,提高页面加载速度(用户看就加载,不看就不加载)
AJAX不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式
2.XML简介:
XML可扩展标记语言
XML被设计用来传输和存储数据
XML和HTML类似,不同的是HTML中都是预定义标签,而XML中没有预定义标签,全都是自定义标签,用来表示一些数据。
比如学生数据用XML表示
但是XML已经被JSON取代了用JSON表示为{“name”,”孙悟空”,”age”:18}
3.AJAX的特点
**优点:可以无需刷新页面与服务器端进行通信。**<br />** 允许你根据用户时间来更新部分页面内容**<br />** 缺点:没有浏览历史,不能回退**<br /> **存在跨域问题(违背浏览器同源策略就是跨域,是浏览器施加的安全限制造成的,简单来说就是当前域名的网站下不能请求非同源的地址(同源指 域名、协议、端口均相同,有一个不同就是跨域))**<br />** SEO不友好(搜索引擎优化)**
4.HTML页面是一个响应体
请求报文
请求行
包含请求方式、请求url(接口)
请求头
Content-Type:告诉服务器,我给你发送的东西是什么格式
User-Agent:可以获取到发请求的浏览器是什么浏览器,版本是什么版本
请求体
GET请求没有请求体 获取数据
POST请求有请求体,请求体就是发送给服务器的数据 发送数据
响应报文
响应行
响应状态码(200–OK、404–服务器没有这个资源、500–服务器内部错误)
响应头
Content-Type:服务器告诉浏览器,给你返回的数据是什么格式
响应体
服务器返回的数据
5.HTTP(hypertext transport protocol)协议(超文本传输协议)
协议详细规定了浏览器和万维网之间的互通规则,约定<br /> *请求报文*(**如果是get请求,请求体是空的,如果是post请求,请求体可以不为空(Form Data里面看)**)<br /> 行 POST /s?ie=uft-8 HTTP/1.1<br /> 头 Host:atguigu.com<br /> Cookie:name=guigu<br /> Content-type:application/x-www-fore-urlencoded<br /> User-Agent:chrom 83<br /> 空行 <br /> 体 username=admin&password&admin<br /> *响应报文*<br /> 行 HTTP/1.1 200 OK<br /> 头 Content-Type:text/html;charset=uft-8<br /> Content-length:2048<br /> Content-encoding:gzip <br /> 空行 <br /> 体 <html><br /> <head><br /> </head><br /> <body><br /> <h1>qcq</h1><br /> </body><br /> </html><br /><br />**浏览器在接到响应结果之后会把相应体内容提取出来做一个解析,最后在页面做一个渲染的呈现**
6.post请求和get请求的异同:
IP和dns的概念:
IP就像家庭地址都是唯一的(有一种比较特殊的是内网Ip地址 因为ip地址不够用,局域网在外部有公用IP地址,内部有属于自己的内网地址。内网和外网通过路由器进行连接和转发(相当于快递员送快递先送到公司的前台,前台再送到员工的工位上,前台相当于路由器,每个工位就是内网IP。内网IP分别有三个地址段 分别是10,192,172开头的 ) ip地址的形态是一串数字,比如118.244.237.94 域名的形态是一个固定形式,比如www.rulejianzhan.com)
DNS:由于IP地址是一串数字不容易记住,要找一个容易记住的东西代替,这个东西就是域名,那DNS就是把域名转换成IP地址的系统(域名就像是门牌号的别名,门牌号不容易记忆,大家都用域名)
http://www.imooc.com?a=1&b=2&c=3(问号之后称为参数 &是和的意思.?是解析时的开始点 ,&是连接参数的符号)
总结:URL结构协议://域名 or IP地址:端口号/目录/文件名.文件后缀?参数=值
传输数据的大小:get的URL会有长度上的限制,则POST上的数据可以非常大
安全性:post比GET安全(get数据会显示在url中所有人都是可见的 有ur参数,还会保存在浏览器历史中 post则相反)
传输数据类型:get请求 只允许ASCII字符,post请求支持多种数据类型
对服务器影响:get请求从服务器上获取数据 也就是查找,不能进行修改。而post请求可以更改服务器数据
get比post的好处:*get比post更快(get有缓存,post不能进行管道化传输,post会先将请求头发送给服务器进行确认然后才真正发送数据,而get会在建立连接后将请求头和请求数据一起发送)
追求速度用get,追求安全用post
7.用浏览器查看请求和响应数据
Response Headers 响应行头 Response响应体<br /> Request Headers请求行头 Form Data请求体
8.状态码:
404找不到,403被禁止,401未授权,500内部错误,2开头表示成功<br />**各类别常见状态码:**
2xx (3种)
200 OK:表示从客户端发送给服务器的请求被正常处理并返回;
204 No Content:表示客户端发送给客户端的请求得到了成功处理,但在返回的响应报文中不含实体的主体部分(没有资源可以返回);
206 Patial Content:表示客户端进行了范围请求,并且服务器成功执行了这部分的GET请求,响应报文中包含由Content-Range指定范围的实体内容。
3xx (5种)
301 Moved Permanently:永久性重定向,表示请求的资源被分配了新的URL,之后应使用更改的URL;
302 Found:临时性重定向,表示请求的资源被分配了新的URL,希望本次访问使用新的URL;
301与302的区别:前者是永久移动,后者是临时移动(之后可能还会更改URL)
303 See Other:表示请求的资源被分配了新的URL,应使用GET方法定向获取请求的资源;
302与303的区别:后者明确表示客户端应当采用GET方式获取资源
304 Not Modified:表示客户端发送附带条件(是指采用GET方法的请求报文中包含if-Match、If-Modified-Since、If-None-Match、If-Range、If-Unmodified-Since中任一首部)的请求时,服务器端允许访问资源,但是请求为满足条件的情况下返回改状态码;
307 Temporary Redirect:临时重定向,与303有着相同的含义,307会遵照浏览器标准不会从POST变成GET;(不同浏览器可能会出现不同的情况);
4xx (4种)
400 Bad Request:表示请求报文中存在语法错误;
401 Unauthorized:未经许可,需要通过HTTP认证;
403 Forbidden:服务器拒绝该次访问(访问权限出现问题)
404 Not Found:表示服务器上无法找到请求的资源,除此之外,也可以在服务器拒绝请求但不想给拒绝原因时使用;
5xx (2种)
500 Inter Server Error:表示服务器在执行请求时发生了错误,也有可能是web应用存在的bug或某些临时的错误时;
503 Server Unavailable:表示服务器暂时处于超负载或正在进行停机维护,无法处理请求;
[
](https://blog.csdn.net/banana960531/article/details/85621865)
9. udp(用户数据报协议面向传输层)和tcp的区别:
*TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接<br /> *TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付<br /> *TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的<br /> *UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)<br /> *每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信<br /> *TCP首部开销20字节;UDP的首部开销小,只有8个字节<br /> *TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道
10.get请求参数设置和post请求体(get没有请求体)
xhr.open('GET','[http://localhost:8080/server?a=100&b=200&c=300')//server](http://localhost:8080/server?a=100&b=200&c=300')//server)后可以设置ge**t请求参数**<br /> post请求体设置 xhr.send('a=100&b=200&c=300')//post在这里设置请求体
11.请求头设置 //设置请求头(身份校验信息放在头信息里面)
//Content-Type设置请求体内容类型<br /> //application/x-www-form-urlencoded参数查询字符串类型<br /> xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')<br />
12.自定义请求头设置 //自定义请求头
xhr.setRequestHeader('name','qcq')//自定义请求头<br /> 服务器端 //all可以接收任意类型的请求<br /> app.all('/server',(request,response) =>{<br /> //如果URL路径请求行的第二段内容是server 则执行回调函数里的代码 并且由response做出响应<br /> //设置响应头设置允许跨域<br /> response.setHeader('Access-Control-Allow-Origin','*')<br /> //设置响应头<br /> response.setHeader('Access-Control-Allow-Headers','*')<br /> response.send('hello post请求头信息')<br /> })
13.服务器端响应json数据
服务器端: //响应一个json数据(send方法里只能接受字符串)<br /> const data = {<br /> name:'qcq',<br /> age:18<br /> }<br /> let str = JSON.stringify(data)<br /> response.send(str)<br /> **html端:自动转换: //自动 设置响应体数据的类型**<br />** xhr.responseType = 'json'**<br /> 手动转换: let data = JSON.parse(xhr,response)<br /> console.log(data)
14.解决IE缓存问题:
xhr.open('GET','[http://localhost:8080/ie?t='+Date.now())](http://localhost:8080/ie?t='+Date.now()))<br /> **IE浏览器由于缓存问题在服务端数据更改之后不能获取到最新数据,所以用时间戳的方式来发送两次不同的请求 会出现不同的url 这样会发新的请求而不会走本地缓存(加一个t='Date.now()')**
15.解决网络超时或者异常:
**html端 //超时2s设置**<br />** xhr.timeout = 2000**<br />** xhr.ontimeout = function(){**<br />** alert("网络异常,请稍后重试")**<br />** }**<br />** //网络异常回调**<br />** xhr.onerror = function(){**<br />** alert('你的网络似乎出了点问题')**<br />** }**<br /> 服务器端:<br /> setTimeout(function(){<br /> response.send('hello 延迟响应')<br /> },3000)
16.取消请求(abort())
服务器端:<br /> setTimeout(function(){<br /> response.send('hello 延迟响应')<br /> },3000)<br /> HTML端<br /> let xhr = null<br /> //绑定事件<br /> btn[0].onclick = function(){<br /> //1.创建对象<br /> xhr = new XMLHttpRequest()<br /> //2.初始化 设置请求方法和url<br /> xhr.open('GET','[http://localhost:8080/delay')](http://localhost:8080/delay'))<br /> //3.发送<br /> xhr.send()//post在这里设置请求体<br /> }<br /> //abort<br /> btn[1].onclick = function(){<br /> xhr.abort()<br /> }<br /> 在控制台看是200显示请求完成 abort ajax的方法需要在里面写一个回调函数,但是要在外部用ajax的对象xhr 所以将xhr放在外部 不能使用const 要用let
17.解决请求重复发送(节流阀)
服务器端:<br /> setTimeout(function(){<br /> response.send('hello 延迟响应')<br /> },3000)<br /> HTML端<br /> *let xhr = null在外面定义<br /> *发送ajax数据前 let issending = false<br /> *创建对象后,修改标识变量的值 issending = true<br /> *当readyState = 4说明发送完毕 issending = false<br /> *当点击事件发生时 判断是否正在发送如果正在发送 则取消发送 if (issending) xhr.abort()
18.jQuery通用方法发送AJAX
服务器端:app.all('/Jquery-server',(request,response) =>{<br /> //如果URL路径请求行的第二段内容是server 则执行回调函数里的代码 并且由response做出响应<br /> //设置响应头设置允许跨域<br /> response.setHeader('Access-Control-Allow-Origin','*')<br /> const data={<br /> name:'hello Jquery'<br /> }<br /> response.send(JSON.stringify(data))})<br /> html端: $('button').eq(0).click(function(){<br /> $.get('[http://localhost:8080/Jquery-server',{a:100,b:200},function(data){](http://localhost:8080/Jquery-server',{a:100,b:200},function(data){)<br /> console.log(data)<br /> $('.result').html(data.name)<br /> <br /> },'json')//如果是post只需要将get改成post<br /> })
19.jQuery发送AJAX
HTMl端:<br /> $('button').eq(1).click(function(){<br /> $.ajax({<br /> //url<br /> url:'[http://localhost:8080/Jquery-server',](http://localhost:8080/Jquery-server',)<br /> //参数<br /> data:{a:100,b:200},<br /> //请求类型<br /> type:'GET',<br /> //响应体结果的设置<br /> dataType:'json',<br /> //成功的回调<br /> success:function(data){<br /> console.log(data)<br /> },<br /> //超出时间<br /> timeout:2000,<br /> //超时回调<br /> error:function(){<br /> console.log('出错啦')<br /> },<br /> //头信息<br /> Headers:{c:300,d:400}<br /> })<br /> })<br /> 服务器端:app.all('/Jquery-server',(request,response) =>{<br /> //如果URL路径请求行的第二段内容是server 则执行回调函数里的代码 并且由response做出响应<br /> //设置响应头设置允许跨域<br /> response.setHeader('Access-Control-Allow-Origin','*')<br /> response.setHeader('Access-Control-Allow-Headers','*')<br /> const data={<br /> name:'hello Jquery'<br /> }<br /> setTimeout(function(){<br /> response.send(JSON.stringify(data)+'延迟响应')<br /> },1000)<br /> })
20.axios通用方法发送AJAX(前端最热门的ajax请求工具包)
get请求: <script src="[https://unpkg.com/axios/dist/axios.min.js"></script>](https://unpkg.com/axios/dist/axios.min.js"></script>)<br /> <script><br /> var btn = document.getElementsByTagName('button')<br /> //配置baseURL<br /> axios.defaults.baseURL = 'http://localhost:8080'<br /> btn[0].onclick=function(){<br /> // //get请求<br /> axios.get('/axios-server',{<br /> //url参数<br /> params:{<br /> id:100,<br /> vip:7},<br /> //请求头信息<br /> headers:{<br /> name:'qcq',<br /> age:18<br /> }<br /> }).then(value => {//回调函数<br /> console.log(value)<br /> })<br /> post请求: <script src="[https://unpkg.com/axios/dist/axios.min.js"></script>](https://unpkg.com/axios/dist/axios.min.js"></script>)<br /> <script><br /> var btn = document.getElementsByTagName('button')<br /> //配置baseURL<br /> axios.defaults.baseURL = 'http://localhost:8080'<br /> btn[0].onclick=function(){<br /> //post请求<br /> axios.post('/axios-server',{//第二个参数是请求体<br /> username:'qcq',<br /> password:'qcq'<br /> },{<br /> //url参数<br /> params:{<br /> id:100,<br /> vip:7},<br /> //请求头信息<br /> headers:{<br /> name:'qcq',<br /> age:18<br /> }<br /> }).then(value => {//回调函数<br /> console.log(value)<br /> })<br /> }
21.axios发送AJAX
axios({<br /> //请求方法<br /> method:'POST',<br /> //url<br /> url:'/axios-server',<br /> //url参数<br /> params:{<br /> id:100,<br /> vip:100},<br /> //请求头信息<br /> headers:{<br /> name:'qcq',<br /> age:24<br /> },<br /> //请求体<br /> data:{<br /> username:'qcq',<br /> password:'qcq'<br /> }<br /> }).then(value => {//回调函数<br /> //响应状态码<br /> console.log(value.status)<br /> //响应状态字符串<br /> console.log(value.statusText)<br /> //头信息<br /> console.log(value.headers)<br /> //响应体<br /> console.log(value.data)<br /> })
22.fetch发送AJAX
fetch('[http://localhost:8080/fetch-server?vip=10'//url](http://localhost:8080/fetch-server?vip=10'//url)参数<br /> ,{<br /> method:'POST',<br /> //请求头信息<br /> headers:{<br /> name:'qcq'<br /> },<br /> //请求体<br /> body:'username=qcq&password=qcq'<br /> }).then(value => {//回调函数<br /> return value.json()<br /> }).then(value => {//回调函数<br /> console.log(value)<br /> })<br /> }
23.jsonp解决跨域问题
1)JSONP 是什么JSONP(JSON with Padding),是一个非官方的跨域解决方案,服务器返回一个函数调用并且把参数传回来,只支持get请求。(前端页面必须提前声明这个函数,否则返回后找不到这个函数会出问题)
缺点:
- 具有局限性, 仅支持get方法
不安全,可能会遭受XSS攻击
2)JSONP怎么工作的?<br /> 在网页有一些标签天生具有跨域能力,比如:img,link iframe script。<br /> JSONP就是利用script标签的跨域能力来发送请求的。<br /> 3)ISONP的使用<br /> 1.动态的创建一个script标签var script= document.createElement("script");<br /> 2.设置script的src,设置回掉函数<br /> 引入cdn本身就是跨域请求服务端代码;//1.引入express<br /> const { response } = require('express')<br /> const express = require('express')<br /> const { request } = require('http')<br /> const app = express()<br /> //jsonp服务 返回前端解析的js代码<br /> app.all('/jsonp-server',(request,response) =>{<br /> const data={<br /> name:'hello jsonp1'<br /> }<br /> //将数据转化为字符串<br /> let str = JSON.stringify(data)<br /> //返回结果<br /> response.end(`handle(${str})`)//end不会加特殊响应头<br /> // response.send("console.log('jsonp')")<br /> })<br /> app.listen(8080,() =>{<br /> console.log('服务已经启动,8080,端口监听中')<br /> })
HTML端代码: <div class="result"></div><br /> <button>点击发送请求</button><br /> <script><br /> //处理数据<br /> function handle(data){<br /> //获取result元素<br /> var result = document.getElementsByClassName('result')[0]<br /> result.innerHTML = data.name<br /> }<br /> </script><br /> <script src="[http://localhost:8080/jsonp-server"></script>](http://localhost:8080/jsonp-server"></script>)<br />**返回的形式是一个函数的调用 而函数的实参就是我们想给客户端返回的结果数据(把参数放到所返回的函数中),这个函数前端必须提前声明,然后在前端函数中对这个参数进行处理**
24.原生jsonp实践
服务端:<br /> //1.引入express<br /> const { response } = require('express')<br /> const express = require('express')<br /> const { request } = require('http')<br /> const app = express()<br /> //jsonp服务 返回前端解析的js代码<br /> app.all('/jsonp-check',(request,response) =>{<br /> const data={<br /> msg:'用户名已经存在'<br /> }<br /> //将数据转化为字符串<br /> let str = JSON.stringify(data)<br /> //返回结果<br /> response.end(`handle(${str})`)//end不会加特殊响应头<br /> // response.send("console.log('jsonp')")<br /> })<br /> app.listen(8080,() =>{<br /> console.log('服务已经启动,8080,端口监听中')<br /> })<br /> HTML端:<br /> 用户名:<input type="text"><br /> <p></p><br /> <script><br /> var input = document.getElementsByTagName('input')[0]<br /> var p = document.getElementsByTagName('p')[0]<br /> //处理数据<br /> function handle(data){<br /> //获取result元素<br /> input.style.border = "solid red 1px"<br /> p.innerHTML = data.msg<br /> }<br /> input.onblur = function(){//获取焦点事件<br /> //获取用户的输入值<br /> var username = this.value<br /> //创建script<br /> var script = document.createElement('script')<br /> script.src = "[http://localhost:8080/jsonp-check"](http://localhost:8080/jsonp-check")<br /> document.body.appendChild(script)<br /> }<br /> </script>
25.jQuery发送jsonp请求
服务端:<br /> //1.引入express<br /> const { response } = require('express')<br /> const express = require('express')<br /> const { request } = require('http')<br /> const app = express()<br /> //jsonp服务 返回前端解析的js代码<br /> app.all('/jsonp-jQuery',(request,response) =>{<br /> const data={<br /> name:'qcq',<br /> city:['bj','sh','sx']<br /> }<br /> //将数据转化为字符串<br /> let str = JSON.stringify(data)<br /> //接收callback参数<br /> let cb = request.query.callback<br /> //返回结果<br /> response.end(`${cb}(${str})`)//end不会加特殊响应头<br /> // response.send("console.log('jsonp')")<br /> })<br /> app.listen(8080,() =>{<br /> console.log('服务已经启动,8080,端口监听中')<br /> })<br /> HTML端:<br /> <div class='result'></div><br /> <button>点击发送请求</button><br /> <script src="./jquery-1.10.1.js"></script><br /> <script><br /> $("button").click(function(){<br /> $.getJSON('[http://localhost:8080/jsonp-jQuery?callback=?',function(data){](http://localhost:8080/jsonp-jQuery?callback=?',function(data){)<br /> $('.result').html(`<br /> 名称:${data.name},<br /> 城市:${data.city}<br /> `<br /> )<br /> })<br /> })<br /> </script>
26.CORS响应头实现跨域
实际上,客户端向浏览器端发送请求,会在请求头上注明origin(来源),无论是同源还是跨域请求资源,服务器端都会给出响应。但是跨域服务器会根据Acceess-Control-Access-Origin来判断origin(来自客户端),若不是可允许的源,服务器端返回的便不是数据而是错误信息,所以我们可以在服务器端设置Access-Control-Allow-Orgin属性,将客户端的地址写进去,便能够获取数据了。
在客户端照常发送数据,在服务器端配置,服务器端的代码如下:
[
](https://blog.csdn.net/xiaofangmin/article/details/104486317)
1)CORS是什么?
coRS( Cross-Origin Resource Sharing),跨域资源共亨。CORS是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持get和post请求。跨域资源共亨标准新增了一组Hp首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源
2)CORS怎么工作的?
CORS是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应以后就会对响应放行。
3)CoRS的使用主要是服务器端的设置
设置://服务器端设置响应头
response.setHeader(‘Access-Control-Allow-Origin’,’‘)
response.setHeader(‘Access-Control-Allow-Headers’,’‘)
response.setHeader(‘Access-Control-Allow-Method’,’‘)
*/
27.原生ajax请求最终代码
window.onload=function () {
_var _btn=document.getElementById('btn')<br /> _var _box=document.getElementById('box')<br /> _var _xhr=null<br /> //为了防止不断地点击发送请求,需要保留最新的请求将上一个请求关掉<br /> //创建一个是否发送的标识<br /> _var _isSending=false<br /> btn.onclick=_function_ () {<br /> //如果正在发送,将上一个发送取消掉<br /> if (isSending) xhr.abort()<br /> //创建对象<br /> xhr = new XMLHttpRequest()<br /> //修改标识变量的值<br /> isSending=true<br /> //自动转换json<br /> xhr.responseType='json'<br /> //超时时间设置<br /> xhr.timeout=2000<br /> //超时回调<br /> xhr.ontimeout=_function_(){<br /> alert('网络超时请重试')<br /> }<br /> //网络异常回调<br /> xhr.onerror=_function_(){<br /> alert('您的网络似乎出了点问题')<br /> }<br /> //初始化+IE浏览器处理缓存?t='+Date.now() 加时间戳<br /> xhr.open('POST', 'http://localhost:8080/cancel?t='+Date.now())<br /> //设置请求头<br /> xhr.setRequestHeader('name','qcq')<br /> //发送(设置请求体)<br /> xhr.send('a=100&b=200&c=300')<br /> //事件取消按钮控制<br /> document.getElementById('btn2').onclick=_function_(){<br /> xhr.abort()//没有块级作用域直接用就可以<br /> }<br /> //事件绑定<br /> xhr.onreadystatechange=_function_ () {<br /> if (xhr.readyState ===4) {<br /> //发送完毕,改变标识<br /> isSending=false<br /> if (200<=xhr.status <300) {<br /> console.log(xhr.status) //状态码<br /> console.log(xhr.statusText) //状态字符串<br /> console.log(xhr.getAllResponseHeaders()) //所有响应头<br /> //1.手动转换json数据<br /> // let data = JSON.parse(xhr.response)<br /> // console.log(data) //响应体<br /> // box.innerHTML = data.name<br /> //2.自动转换json数据<br /> console.log(xhr.response) //响应体<br /> <br /> <br /> }<br /> }<br /> }<br /> }<br /> }
28. ajax、axios、fetch的区别
(1)AJAX Ajax 即“AsynchronousJavascriptAndXML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。它是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面。其缺点如下:
- 本身是针对MVC编程,不符合前端MVVM的浪潮
- 基于原生XHR开发,XHR本身的架构不清晰
- 不符合关注分离(Separation of Concerns)的原则
- 配置和调用方式非常混乱,而且基于事件的异步模型不友好。
(2)Fetch fetch号称是AJAX的替代品,是在ES6出现的,使用了ES6中的promise对象。Fetch是基于promise设计的。Fetch的代码结构比起ajax简单多。fetch不是ajax的进一步封装,而是原生js,没有使用XMLHttpRequest对象。
fetch的优点:
- 语法简洁,更加语义化
- 基于标准 Promise 实现,支持 async/await
- 更加底层,提供的API丰富(request, response)
- 脱离了XHR,是ES规范里新的实现方式
fetch的缺点:
- fetch只对网络请求报错,对400,500都当做成功的请求,服务器返回 400,500 错误码时并不会 reject,只有网络错误这些导致请求不能完成时,fetch 才会被 reject。
- fetch默认不会带cookie,需要添加配置项: fetch(url, {credentials: ‘include’})
- fetch不支持abort,不支持超时控制,使用setTimeout及Promise.reject的实现的超时控制并不能阻止请求过程继续在后台运行,造成了流量的浪费
- fetch没有办法原生监测请求的进度,而XHR可以
(3)Axios Axios 是一种基于Promise封装的HTTP客户端,其特点如下:
- 浏览器端发起XMLHttpRequests请求
- node端发起http请求
- 支持Promise API
- 监听请求和返回
- 对请求和返回进行转化
- 取消请求
- 自动转换json数据
- 客户端支持抵御XSRF攻击
函数防抖
是指在事件被触发 n 秒后再执行回调,如果在这 n 秒内事件又被触发,则重新计时。这可以使用在一些点击请求的事件上,避免因为用户的多次点击向后端发送多次请求。
// 函数防抖的实现
function debounce(fn, wait) {
let timer = null;
return function() {
let context = this,
args = arguments;
// 如果此时存在定时器的话,则取消之前的定时器重新记时<br /> if (timer) {<br /> clearTimeout(timer);<br /> timer = null;<br /> }// 设置定时器,使事件间隔指定事件后执行<br /> timer = setTimeout(() => {<br /> fn.apply(context, args);<br /> }, wait);<br /> };<br />}<br />复制代码
手写节流函数
函数节流是指规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。节流可以使用在 scroll 函数的事件监听上,通过事件节流来降低事件调用的频率。
// 函数节流的实现;
function throttle(fn, delay) {
let curTime = Date.now();
return function() {
let context = this,
args = arguments,
nowTime = Date.now();
// 如果两次时间间隔超过了指定时间,则执行函数。<br /> if (nowTime - curTime >= delay) {<br /> curTime = Date.now();<br /> return fn.apply(context, args);<br /> }<br /> };<br />}
