ASynchronous JavaScript And XML
- 异步和同步:在客户端和服务器端相互通信的基础上
- 同步:客户端必须等待服务器端的响应。在等待的期间客户端不能做其他操作。
- 异步:客户端不需要等待服务器端的响应。在服务器处理请求的过程中,客户端可以进行其他的操作。
- Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
- 可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
- 传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面。
- 可以提升用户的体验
注意事项
服务器响应的数据,在客户端要想当做json数据格式使用, 需要在服务端设置MIME类型 content-type=application/json;charset=utf-8
js原生方式
1 | //1.创建核心对象 |
JQeury方式
$.ajax()
语法:
$.ajax({键值对})
;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15//使用$.ajax()发送异步请求
$.ajax({
url:"ajaxServlet1111" , // 请求路径
type:"POST" , //请求方式
//data: "username=jack&age=23",//请求参数
data:{"username":"jack","age":23},
success:function (data) {
alert(data);
},//响应成功后的回调函数
error:function () {
alert("出错啦...")
},//表示如果请求响应出现错误,会执行的回调函数
dataType:"text"//设置接受到的响应数据的格式
});
$.get()
:发送get请求- 语法:
$.get(url, [data], [callback], [type])
- url:请求路径
- data:请求参数
- callback:回调函数
- 语法:
- type:响应结果的类型
$.post()
:发送post请求- 语法:
$.post(url, [data], [callback], [type])
- 语法:
fetch发送异步请求
常用配置选项
- method(String)
- body(String)
- headers(Object)
示例
1 | fetch("http://localhost/products", {method: "GET"}) |
axios发送异步请求
1 | // 请求拦截器, 在请求发出前设置一些信息 |
同源政策
如果两个页面拥有相同的协议(http/https)、域名和端口,那么这两个页面就属于统一个源。
同源政策的目的就是为了保证用户信息的安全。
同源限制
- A网站在客户端设置的Cookie,B网站不能访问
- 向非同源的地址发送ajax请求,浏览器会拒绝接收(但能发送请求)。
Jsonp
json with padding, 不属于ajax请求,但可以模拟ajax请求,解决同源限制问题。
实现步骤
- 将不同源的请求地址写道script标签的src属性中,并设置请求参数callbak
- 服务器端响应一个函数调用的字符串,让客户端调用。
1 | <body> |
CORS跨域资源共享
优质博文: https://www.ruanyifeng.com/blog/2016/04/cors.html
Cross-origin resource sharing, 允许浏览器向跨域服务器发送Ajax请求。
CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能 。整个CORS通信过程,都是浏览器自动完成,不需要用户参与。 因此,实现CORS通信的关键是服务器。
简单请求
- 请求方法是一下三者之一:HEAD、GET、POST
- HTTP头不能超过一下几种字段:
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-Type:只限于三个值
application/x-www-form-urlencoded
、multipart/form-data
、text/plain
浏览器发现是简单请求的跨域访问时会携带origin头信息,服务器端如果允许来自这个源的请求,就会响应一个Access-Control-Allow-Origin头,则本次跨域请求会成功。
特殊请求
不符合简单请求的条件,会被浏览器判定为特殊请求。
特殊请求会在正式通信之前,增加一次HTTP查询请求,称为”预检”请求(preflight)。
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest
请求,否则就报错。
一个“预检”请求的样板:
1 | OPTIONS /cors HTTP/1.1 |
与简单请求相比,除了Origin以外,多了两个头:
- Access-Control-Request-Method:接下来会用到的请求方式,比如PUT
- Access-Control-Request-Headers:会额外用到的头信息
服务的收到预检请求,如果许可跨域,会发出响应:
1 | HTTP/1.1 200 OK |
除了Access-Control-Allow-Origin
和Access-Control-Allow-Credentials
以外,这里又额外多出3个头:
- Access-Control-Allow-Methods:允许访问的方式
- Access-Control-Allow-Headers:允许携带的头
- Access-Control-Max-Age:本次许可的有效时长,单位是秒,过期之前的ajax请求就无需再次预检
如果浏览器得到上述响应,则认定为可以跨域,后续就跟简单请求的处理是一样的了。
服务器端设置响应头
- Access-Control-Allow-Origin:设置允许的来源
- Access-Control-Allow-Method:设置允许的请求类型
- Access-Control-Allow-Headers:设置默认不能拿到的字段(
XMLHttpRequest
对象的getResponseHeader()
方法只能拿到6个基本字段 )
解决方案3
由于同源政策时浏览器给Ajax的限制,服务器端是不存在同源政策限制的。
跨域访问携带Cookie
在使用Ajax发送跨域请求时,默认情况下不会携带Cookie信息
实现
- 客户端将XMLHttpRequest对象的withCredentials属性设置为ture,表示跨域请求时携带Cookie
- 浏览器端设置
Access-Control-Allow-Credentials:true
, 表示允许客户端携带cookie
springmvc解决跨域问题
方法1:使用CorssOrign注解
方法2:注册一个CorsFilter
1 | import org.springframework.context.annotation.Bean; |