传统请求
传统请求有哪些?
- 浏览器地址栏输入url
- 超链接
- form表单submit提交
- 使用js代码发送请求
传统请求的缺点
- 页面全部刷新导致用户体验感较差
- 用户体验感有空白期,因为会先清空旧页面,再展示新页面,当服务器响应时间较长时,页面会展示空白
那么如何实现页面的局部刷新呢?ajax可以实现
什么是ajax
Ajax即Asynchronous Javascript And XML(异步JavaScript和XML)在 2005年被Jesse James Garrett提出的新术语,用来描述一种使用现有技术集合的‘新’方法,包括: HTML 或 XHTML, CSS, JavaScript, DOM, XML, XSLT, 以及最重要的XMLHttpRequest。 [3] 使用Ajax技术网页应用能够快速地将增量更新呈现在用户界面上,而不需要重载(刷新)整个页面,这使得程序能够更快地回应用户的操作
--- 百度百科
ajax概述
- ajax不能称为一种技术,它是多种技术的综合产物
- ajax可以让那个浏览器发送一种特殊请求,这种请求可以是异步的
- ajax可能使用XML、JSON字符串或者纯文本字符串来传输数据
- ajax可更新网页部分内容,实现局部刷新
- ajax可做到同一个网页同时发送多个请求
ajax是如何实现页面的局部刷新的?
XMLHttpRequest对象
- XMLHttpRequest对象是ajax的核心对象
- XMLHttpRequest对象是现代浏览器的内置对象
- 创建XMLHttpRequest对象,
var xhr = new XMLHttpRequest() - XMLHttpRequest对象的方法:
// 取消请求
abort()
// 获取所有响应头字段
getAllResponseHeaders()
// 获取响应头字段
getResponseHeader()
// 开启通道
open(method,URL,async)
// 发送get请求
send()
// 发送post请求
send(string)
// 设置请求头字段
setRequestHeader()
- XMLHttpRequest对象的属性:
//readystate改变时的回调函数
onreadystatechange
// 记录XMLHttpRequest对象状态
// 0:请求未初始化,1:服务器连接已建立,2:请求已收到,3:正在处理请求,4:请求已完成且响应已就绪
readystate
// 传输数据格式是字符串时,用此属性获取数据
responseText
// 传输数据格式是XML时,用此属性获取数据
responseXML
// http请求状态码
status
// http请求状态文字
statusText
发送get请求
let username = 'xf'
let age = 18
// 创建实例对象
var xhr = new XMLHttpRequest()
// 注册回调函数
xhr.onreadystate = function(){}
// 打开通道,url?后是get请求的参数,&连接多个参数
xhr.open('GET',‘/a?username=’+username+'&age='+age,true)
// 发送请求
xhr.send()
发送post请求
let username = 'xf'
let age = 18
// 创建实例对象
var xhr = new XMLHttpRequest()
// 注册回调函数
xhr.onreadystate = function(){}
// 打开通道
xhr.open('POST',‘/a‘,true)
// post要传递参数必须设置这个请求头字段,设置头必须在通道打开后
xhr.setRequestHeader('content-type','application/x-www-form-urlencoded')
// 发送请求
xhr.send(‘username=’+username+'&age='+age)
ajax的同步请求和异步请求
同步请求?
两个ajax请求,请求2要在请求1结束后才能发送
open()方法的第三个参数指定该请求是同步还是异步
xhr.open(method,url,false)该请求发送后,其他请求要等该请求结束后才能发送
异步请求?
两个ajax请求。可以同时并发,无需等待对方结束
xhr.open(method,url,true)该请求发送后不影响其他请求的发送
跨域问题
什么是跨域
浏览器有一种安全策略:同源策略,协议、域名、端口三个都一样就是同源的,其中有一个不一样就是非同源的,不同源之间的请求可能会跨域
跨域出现的根本原因:跨域的时候,不允许共享同一个XMLHttpRequest对象,因为共享同一个XMLHttpRequest对象是不安全的,同源可以共享XMLHttpRequest对象
不会跨域的情况(不涉及到XMLHttpRequest对象)
- 超链接
- form表单发送请求
- window.location.href/document.location.href
- script标签src加载js
- img的src加载图片资源
ajax请求跨域解决方案
- 设置响应头字段,Access-Control-Allow-Origin
核心原理:跨域访问的资源允许你访问
response.setHeader('Access-Control-Allow-origin','具体允许的站点‘ 或者 *) // *:全部
-
jsonp:json with padding(带填充的json)
jsonp不是一个真正的ajax请求,但是可以局部刷新,借助了script标签可以跨域的特点来实现
具体实现:
- 前端定义一个回调函数
- script标签中的src写要请求的后端接口
- 后端接受请求后,响应一段js代码(函数调用)
- 前端接收到响应数据后,执行该js代码(调用定义的回调函数,回调函数里的参数就是后端返回的查询到的数据)
简单代码实现:
前端代码
<script type='text/javascript'>
// 回调函数,data就是后端返回的数据
function getInfo(data){
console.log(data)
}
</script>
// 请求后得到后端响应内容(‘func(数据)’),执行该js代码(调用回调函数)
<script type='text/javascript' scr="/a?func=getInfo"></script>
后端代码:
String func = request.getParameter('func')
response.getWriter().print(func+'(要返回的数据)')
- jQuery封装的jsonp
- 代理机制
同源策略是浏览器的安全策略,服务器之间的请求是不会跨域的,
所以可以使用一个代理服务器,向同源的代理服务器发请求,代理服务器再向目标服务器去请求,
目标服务器查询到数据后,返回给代理服务器,代理服务器拿到数据后返回给浏览器,
使用的代理服务器和浏览器是同源的,没有跨域,代理服务器和目标服务器之间不存在跨域问题,因此解决了跨域问题
- nginx反向代理
本质上也是使用了代理机制来完成ajax的跨域,只需要修改一个nginx配置即可