ajax:
不重新加载整个页面的情况下(局部刷新),与服务器交换数据。这种异步交互的方式,使用户单击后,不必刷新页面也能获取新数据。
我们使用XMLHttpRequest
对象来进行异步数据查询、检索、发送一个Ajax
请求。
XMLHttpRequest在IE下和在Firefox中的不同建设方式:
IE:
new ActiveXObject()
Firefox:
new XMLHttpRequest()
原生ajax:
ajax的参数(五个常用):
$.ajax({
1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址。
2.type: 请求方式(post或get)默认为get。注意其他http请求方法,例如put和delete也可以使用,但仅部分浏览器支持。
3. data: 要求为Object或String类型的参数,发送到服务器的数据。如果不是字符串,将自动转换为字符串格式,get请求中将附加在url后面
4.dataType: 表示服务器返回的数据类型,要求为String类型的参数。如果不指定,JQuery将自动根据http包mime信息返回responseXML或responseText,并作为回调函数参数传递。可用的类型如下:
xml:返回XML文档,可用JQuery处理。
html:返回纯文本HTML信息;包含的script标签会在插入DOM时执行。
script:返回纯文本JavaScript代码。不会自动缓存结果。除非设置了cache参数。注意在远程请求时(不在同一个域下),所有post请求都将转为get请求。
json:返回JSON数据。
jsonp:JSONP格式。使用SONP形式调用函数时,例如myurl?callback=?,JQuery将自动替换后一个“?”为正确的函数名,以执行回调函数。
text:返回纯文本字符串。
5.success:function(): 要求为Function类型的参数,请求成功后调用的回调函数。
6.async: Boolean类型的参数,默认为true异步,如果要同步设为false,同步的话就是用户其他操作必须等待请求完成才可以执行。
7.cache: cache的作用就是第一次请求完毕之后,如果再次去请求,可以直接从缓存里面读取而不是再到服务器端读取。
})
利用AJAX可以做:
- 注册时,输入用户名自动检测用户是否已经存在。
- 登陆时,提示用户名密码错误。
- 删除数据行时,将行ID发送到后台,后台在数据库中删除,数据库删除成功后,在页面DOM中将数据行也删除。
Jquery是ajax封装的一个类库
直接封装好的 $ . ajax ( ) 用的比较多
$ . get ( ) $ . post ( )
跨域:
浏览器的同源策略导致ajax无法进行跨域传输,
浏览器同源策略并不是对所有的请求均制约:
- 制约: XmlHttpRequest
- 不制约: img、iframe、script等具有src属性的标签
一、jsonp(只支持GET请求)
原理是:动态插入script
标签,通过script
标签用src引入一个js
文件,这个js文件载入成功后会执行我们在url参数中指定的函数,并且会把我们需要的json
数据作为参数传入。
xmlRequesthtml是制约条件,src无跨域限制
优点:
是兼容性好,简单易用,支持浏览器与服务器双向通信。
JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据
缺点:
1.是只能使用Get请求
2.不能注册success、error等事件监听函数,不能很容易的确定JSONP请求是否失败
3.JSONP是从其他域中加载代码执行,容易受到跨站请求伪造的攻击,其安全性无法确保(前端攻击)
JSONP
:json+padding
(内填充),顾名思义,就是把JSON填充到一个盒子里
二、CORS(跨域资源共享)
CORS需要浏览器和服务器同时支持。其他的都兼容,IE浏览器不能低于IE10。
整个CORS通信过程,都是浏览器自动完成,不需要用户参与。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,主要就是通过设置Access-Control-Allow-Origin
来进行的,有时还会多出一次附加的请求,如果浏览器检测到相应的设置,就可以允许Ajax
进行跨域的访问。但用户不会有感觉。
因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨域通信。
JSONP只支持GET
请求,CORS支持所有类型的HTTP请求。
跨域请求默认不会携带Cookie信息,如果需要携带,请配置下述参数:
"Access-Control-Allow-Credentials": true
// Ajax设置
"withCredentials": true
cors请求分为简单请求和非简单请求:
只要同时满足两个条件,就属于简单请求。
(1) 请求方法是以下三种方法之一:
HEAD
GET
POST
(2)HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
凡是不同时满足上面两个条件,就属于非简单请求。
浏览器对这两种请求的处理,是不一样的。
简单请求:
对于简单请求,浏览器直接发出CORS请求。具体来说,就是在头信息之中,增加一个Origin字段。
Origin字段用来说明,本次请求来自哪个源(协议 + 域名 + 端口)。服务器根据这个值,决定是否同意这次请求。
如果Origin指定的源,不在许可范围内,服务器会返回一个正常的HTTP回应。浏览器发现,这个回应的头信息没有包含Access-Control-Allow-Origin字段(详见下文),就知道出错了,从而抛出一个错误,被XMLHttpRequest的onerror回调函数获取到。
如果Origin指定的域名在许可范围内,服务器返回的响应,会多出几个头信息字段。
Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8
需要注意的是,如果要发送Cookie,Access-Control-Allow-Origin就不能设为星号,必须指定明确的、与请求网页一致的域名。同时,Cookie依然遵循同源政策,只有用服务器域名设置的Cookie才会上传,其他域名的Cookie并不会上传,且(跨源)原网页代码中的document.cookie也无法读取服务器域名下的Cookie。
非简单请求
4.1 预检请求
非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json。
预检:非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求。(preflight)。
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。
第三种:跨域传输cookie
在跨域请求中,默认情况下,HTTP Authentication信息,Cookie头以及用户的SSL证书无论在预检请求中或是在实际请求都是不会被发送。
如果想要发送:
- 浏览器端:XMLHttpRequest的withCredentials为true
- 服务器端:Access-Control-Allow-Credentials为true
- 注意:服务器端响应的 Access-Control-Allow-Origin 不能是通配符 *
第四种:document.domain
第五种:window.name+iframe
6、AJAX请求总共有多少种CALLBACK。
Ajax请求总共有八种Callback
1、onSuccess
2、onFailure
3、onUninitialized
4、onLoading
5、onLoaded
6、onInteractive
7、onComplete
8、onException
XMLHttpRequest:
如何获取response header
xhr
提供了2个用来获取响应头部的方法:getAllResponseHeaders
和getResponseHeader
。前者是获取 response 中的所有header 字段,后者只是获取某个指定 header 字段的值。另外,getResponseHeader(header)
的header
参数不区分大小写。
DOMString getAllResponseHeaders();
DOMString getResponseHeader(DOMString header);
这2个方法看起来简单,但却处处是坑儿。
你是否遇到过下面的坑儿?——反正我是遇到了。。。
-
使用
getAllResponseHeaders()
看到的所有response header
与实际在控制台Network
中看到的response header
不一样 -
使用
getResponseHeader()
获取某个header
的值时,浏览器抛错Refused to get unsafe header "XXX"
xhr.responseType
responseType
是xhr level 2
新增的属性,用来指定xhr.response
的数据类型,目前还存在些兼容性问题,可以参考本文的【XMLHttpRequest
的兼容性】这一小节。那么responseType
可以设置为哪些格式呢,我简单做了一个表,如下:
值 | xhr.response 数据类型 | 说明 |
---|---|---|
"" | String 字符串 | 默认值(在不设置responseType 时) |
"text" | String 字符串 | |
"document" | Document 对象 | 希望返回 XML 格式数据时使用 |
"json" | javascript 对象 | 存在兼容性问题,IE10/IE11不支持 |
"blob" | Blob 对象 | |
"arrayBuffer" | ArrayBuffer 对象 |
如何获取上传、下载的进度
在上传或者下载比较大的文件时,实时显示当前的上传、下载进度是很普遍的产品需求。
我们可以通过onprogress
事件来实时显示进度,默认情况下这个事件每50ms触发一次。需要注意的是,上传过程和下载过程触发的是不同对象的onprogress
事件:
-
上传触发的是
xhr.upload
对象的onprogress
事件 -
下载触发的是
xhr
对象的onprogress
事件
xhr.onprogress = updateProgress;
xhr.upload.onprogress = updateProgress;
function updateProgress(event) {
if (event.lengthComputable) {
var completedPercent = event.loaded / event.total;
}
}