1.认识ajax
1.1 什么是ajax
异步 JavaScript 和 XML,或 Ajax 本身不是一种技术,而是一种将一些现有技术结合起来使用的方法,包括:HTML 或 XHTML、CSS、JavaScript、DOM、XML、XSLT、以及最重要的 XMLHttpRequest 对象。
尽管ajax中x代表的是xml,但是由于json优越的综合性能,更多的时候我们经常用的是json
1.2 ajax的作用
使用结合了这些技术的 Ajax 模型以后,网页应用能够快速地将增量更新呈现在用户界面上,而不需要重载(刷新)整个页面。这使得程序能够更快地回应用户的操作.
2.ajax的基本用法
2.1 使用XMLHttpRequest
2.1.1 什么是XMLHttpRequest
XMLHttpRequest 对象的 responseType 属性可以被设置来改变服务器的预期响应类型。可能的值是空字符串(默认)、arraybuffer、blob、document、json 和 text。response 属性将根据 responseType 包含,作为一个 ArrayBuffer、Blob、Document、JSON 或字符串的实体主体
2.1.2 如何使用XMLHttpRequest
- 创建XMLHttpRequest 对象
const xhr = new XMLHttpRequest()
- 在创建好XMLHttpRequest 对象之后可以立即对xhr进行事件监听
xhr.onreadystatechange = ()=>{
// addEventListener()不支持ie8以下
if(xhr.readyState !== 4) return
//为了兼容性 未使用this
if((xhr.status>=200&xhr.status<300)||
xhr.status == 304){
// console.log('可以正常使用相应数据');
console.log(xhr.responseText)
}
}
- open()准备发送数据
- open() 的第一个参数是 HTTP 请求方法——GET,POST,HEAD 以及服务器支持的其他方法。根据 HTTP 标准的要求,保证这些方法一定要是大写字母,否则其他一些浏览器(比如 FireFox)可能无法处理这个请求。
- 第二个参数是你要发送请求的 URL。由于安全原因,默认不能调用第三方 URL 域名。确保你在页面中使用的是正确的域名,否则在调用 open() 方法时会有 “permission denied” 错误提示。一个容易犯的错误是你企图通过 domain.tld 访问网站,而不是使用 www.domain.tld
- 第三个参数是可选的,用于设置请求是否是异步的。如果设为 true(默认值),即开启异步,JavaScript 就不会在此语句阻塞,使得用户能在服务器还没有响应的情况下与页面进行交互。这就是 AJAX 中的第一个 A。
xhr.open("GET", "http://www.example.org/some.file", true);
- send()方法发送数据
send() 方法的参数可以是任何你想发送给服务器的内容,如果是 POST 请求的话。发送表单数据时应该用服务器可以解析的格式,像查询字符串:
"name=value&anothername="+encodeURIComponent(myVar)+"&so=on"
或者使用其他格式,类似 multipart/form-data、JSON、XML 等。
如果你使用 POST 数据,那就需要设置请求的 MIME 类型。比如,在调用 send() 方法获取表单数据前要有下面这个:
xhr.setRequestHeader(
"Content-Type",
"application/x-www-form-urlencoded"
);
- response或者responseText接受返回数据
值得注意的是response的兼容性问题
responseText:以文本字符串的方式返回服务器响应。
responseXML:以 XMLDocument 对象的形式返回服务器响应,你可以使用 JavaScript DOM 函数来遍历它。
2.1.3 readyState的状态值
- 0(未初始化)或(请求还未初始化)
- 1(正在加载)或(已建立服务器链接)
- 2(已加载)或(请求已接收)
- 3(交互)或(正在处理请求)
- 4(完成)或(请求已完成并且响应已准备好)
2.1.4 其他补充
在监听xhr事件的时候,我们不仅判断了readystate的状态值,还判断了http的响应状态,
if((xhr.status>=200&xhr.status<300)||
xhr.status == 304)
2.1.5 简单示例
<button id="ajaxButton" type="button">发送请求</button>
<script>
(() => {
let httpRequest;
document
.getElementById("ajaxButton")
.addEventListener("click", makeRequest);
function makeRequest() {
httpRequest = new XMLHttpRequest();
if (!httpRequest) {
alert("放弃了 :( 不能创建 XMLHTTP 实例");
return false;
}
httpRequest.onreadystatechange = alertContents;
httpRequest.open("GET", "test.html");
httpRequest.send();
}
function alertContents() {
if (httpRequest.readyState === XMLHttpRequest.DONE) {
if (httpRequest.status === 200) {
alert(httpRequest.responseText);
} else {
alert("请求遇到了问题。");
}
}
}
})();
</script>
3.axios中的ajax
3.1 axios是什么
Axios 是一个基于 promise 网络请求库,作用于node.js 和浏览器中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests。
3.2 axios的特性
- 从浏览器创建 XMLHttpRequests
- 从 node.js 创建 http 请求
- 支持 Promise API
- 拦截请求和响应
- 转换请求和响应数据
- 取消请求
- 自动转换JSON数据
- 客户端支持防御XSRF
3.3 axios的配置
- npm
npm install axios
- bower
bower install axios
- yarn
yarn add axios
- jsDelivr CDN
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
- unpkg CDN
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
注意:使用cdn模式引入一般是较新的版本,我们可以通过查看跳转查询cdn使用的版本或者更换版本
3.4 axios的使用
- axios(config)
// 发起一个post请求
axios({
method: 'post',
url: '/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
}
});
// 在 node.js 用GET请求获取远程图片
axios({
method: 'get',
url: 'http://bit.ly/2mTM3nY',
responseType: 'stream'
})
.then(function (response) {
response.data.pipe(fs.createWriteStream('ada_lovelace.jpg'))
});
- axios(url[, config])
axios(url,{
method:'post',
timeout:1000,
headers:{
'Content-Type': 'application/x-www-form-urlencoded',
},
// 请求头携带数据
params:{
usename:'zhqi'
},
// 请求体携带数据
data:'age=18&name=zhqi'
}).then(response=>{
console.log(response);
}).catch(err=>{
console.log(err);
})
- 其他方法
axios.request(config)
axios.get(url[, config])
axios.delete(url[, config])
axios.head(url[, config])
axios.options(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])
3.5 axios实例
- axios.create([config])
const instance = axios.create({
baseURL: 'https://some-domain.com/api/',
timeout: 1000,
headers: {'X-Custom-Header': 'foobar'}
});
- 实例方法
以下是可用的实例方法。指定的配置将与实例的配置合并。
axios#request(config)
axios#get(url[, config])
axios#delete(url[, config])
axios#head(url[, config])
axios#options(url[, config])
axios#post(url[, data[, config]])
axios#put(url[, data[, config]])
axios#patch(url[, data[, config]])
axios#getUri([config]) - 请求配置
这些是创建请求时可以用的配置选项。只有 url 是必需的。如果没有指定 method,请求将默认使用 GET 方法。
{
// `url` 是用于请求的服务器 URL
url: '/user',
// `method` 是创建请求时使用的方法
method: 'get', // 默认值
// `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
// 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL
baseURL: 'https://some-domain.com/api/',
// `transformRequest` 允许在向服务器发送前,修改请求数据
// 它只能用于 'PUT', 'POST' 和 'PATCH' 这几个请求方法
// 数组中最后一个函数必须返回一个字符串, 一个Buffer实例,ArrayBuffer,FormData,或 Stream
// 你可以修改请求头。
transformRequest: [function (data, headers) {
// 对发送的 data 进行任意转换处理
return data;
}],
// `transformResponse` 在传递给 then/catch 前,允许修改响应数据
transformResponse: [function (data) {
// 对接收的 data 进行任意转换处理
return data;
}],
// 自定义请求头
headers: {'X-Requested-With': 'XMLHttpRequest'},
// `params` 是与请求一起发送的 URL 参数
// 必须是一个简单对象或 URLSearchParams 对象
params: {
ID: 12345
},
// `paramsSerializer`是可选方法,主要用于序列化`params`
// (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)
paramsSerializer: function (params) {
return Qs.stringify(params, {arrayFormat: 'brackets'})
},
// `data` 是作为请求体被发送的数据
// 仅适用 'PUT', 'POST', 'DELETE 和 'PATCH' 请求方法
// 在没有设置 `transformRequest` 时,则必须是以下类型之一:
// - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
// - 浏览器专属: FormData, File, Blob
// - Node 专属: Stream, Buffer
data: {
firstName: 'Fred'
},
// 发送请求体数据的可选语法
// 请求方式 post
// 只有 value 会被发送,key 则不会
data: 'Country=Brasil&City=Belo Horizonte',
// `timeout` 指定请求超时的毫秒数。
// 如果请求时间超过 `timeout` 的值,则请求会被中断
timeout: 1000, // 默认值是 `0` (永不超时)
// `withCredentials` 表示跨域请求时是否需要使用凭证
withCredentials: false, // default
// `adapter` 允许自定义处理请求,这使测试更加容易。
// 返回一个 promise 并提供一个有效的响应 (参见 lib/adapters/README.md)。
adapter: function (config) {
/* ... */
},
// `auth` HTTP Basic Auth
auth: {
username: 'janedoe',
password: 's00pers3cret'
},
// `responseType` 表示浏览器将要响应的数据类型
// 选项包括: 'arraybuffer', 'document', 'json', 'text', 'stream'
// 浏览器专属:'blob'
responseType: 'json', // 默认值
// `responseEncoding` 表示用于解码响应的编码 (Node.js 专属)
// 注意:忽略 `responseType` 的值为 'stream',或者是客户端请求
// Note: Ignored for `responseType` of 'stream' or client-side requests
responseEncoding: 'utf8', // 默认值
// `xsrfCookieName` 是 xsrf token 的值,被用作 cookie 的名称
xsrfCookieName: 'XSRF-TOKEN', // 默认值
// `xsrfHeaderName` 是带有 xsrf token 值的http 请求头名称
xsrfHeaderName: 'X-XSRF-TOKEN', // 默认值
// `onUploadProgress` 允许为上传处理进度事件
// 浏览器专属
onUploadProgress: function (progressEvent) {
// 处理原生进度事件
},
// `onDownloadProgress` 允许为下载处理进度事件
// 浏览器专属
onDownloadProgress: function (progressEvent) {
// 处理原生进度事件
},
// `maxContentLength` 定义了node.js中允许的HTTP响应内容的最大字节数
maxContentLength: 2000,
// `maxBodyLength`(仅Node)定义允许的http请求内容的最大字节数
maxBodyLength: 2000,
// `validateStatus` 定义了对于给定的 HTTP状态码是 resolve 还是 reject promise。
// 如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`),
// 则promise 将会 resolved,否则是 rejected。
validateStatus: function (status) {
return status >= 200 && status < 300; // 默认值
},
// `maxRedirects` 定义了在node.js中要遵循的最大重定向数。
// 如果设置为0,则不会进行重定向
maxRedirects: 5, // 默认值
// `socketPath` 定义了在node.js中使用的UNIX套接字。
// e.g. '/var/run/docker.sock' 发送请求到 docker 守护进程。
// 只能指定 `socketPath` 或 `proxy` 。
// 若都指定,这使用 `socketPath` 。
socketPath: null, // default
// `httpAgent` and `httpsAgent` define a custom agent to be used when performing http
// and https requests, respectively, in node.js. This allows options to be added like
// `keepAlive` that are not enabled by default.
httpAgent: new http.Agent({ keepAlive: true }),
httpsAgent: new https.Agent({ keepAlive: true }),
// `proxy` 定义了代理服务器的主机名,端口和协议。
// 您可以使用常规的`http_proxy` 和 `https_proxy` 环境变量。
// 使用 `false` 可以禁用代理功能,同时环境变量也会被忽略。
// `auth`表示应使用HTTP Basic auth连接到代理,并且提供凭据。
// 这将设置一个 `Proxy-Authorization` 请求头,它会覆盖 `headers` 中已存在的自定义 `Proxy-Authorization` 请求头。
// 如果代理服务器使用 HTTPS,则必须设置 protocol 为`https`
proxy: {
protocol: 'https',
host: '127.0.0.1',
port: 9000,
auth: {
username: 'mikeymike',
password: 'rapunz3l'
}
},
// see https://axios-http.com/zh/docs/cancellation
cancelToken: new CancelToken(function (cancel) {
}),
// `decompress` indicates whether or not the response body should be decompressed
// automatically. If set to `true` will also remove the 'content-encoding' header
// from the responses objects of all decompressed responses
// - Node only (XHR cannot turn off decompression)
decompress: true // 默认值
}
- 基本实例
axios.post(url,{
username:'zhqi'
})
.then(response=>{
console.log(response);
})
.catch(err=>{
console.log(err);
})
3.6 注意事项
- axios 依赖原生的ES6 Promise实现而被支持。 如果你的环境不支持 ES6 Promise,你可以使用polyfill。、
- axios 包含 TypeScript 类型定义。
4.fetch的ajax
4.1 什么是fetch
Fetch API 提供了一个 JavaScript 接口,用于访问和操纵 HTTP 管道的一些具体部分,例如请求和响应。它还提供了一个全局 fetch() 方法,该方法提供了一种简单,合理的方式来跨网络异步获取资源
简单来说:fetch是为了替代jq.ajax的。但是由于出现较晚,兼容性较差。
4.2 fetch 与 jQuery.ajax
- 当接收到一个代表错误的 HTTP 状态码时,从 fetch() 返回的 Promise 不会被标记为 reject,即使响应的 HTTP 状态码是 404 或 500。相反,它会将 Promise 状态标记为 resolve(如果响应的 HTTP 状态码不在 200 - 299 的范围内,则设置 resolve 返回值的 ok 属性为 false),仅当网络故障时或请求被阻止时,才会标记为 reject。
- fetch 不会发送跨域 cookie,除非你使用了 credentials 的初始化选项。(自 2018 年 8 月以后,默认的 credentials 政策变更为 same-origin。Firefox 也在 61.0b13 版本中进行了修改)
4.3 fetch简单实例
fetch(url)
.then(res => {
if (res.ok) {
return res.json()
}else{
throw new Error(`异常`,res.status)
}
})
.then(data => {
console.log(data);
})
.catch(err => {
console.log(err);
})
4.4fetch的参数
fetch() 接受第二个可选参数,一个可以控制不同配置的 init 对象:
一个配置项对象,包括所有对请求的设置。可选的参数有:
- method: 请求使用的方法,如 GET、POST。
- headers: 请求的头信息,形式为 Headers 的对象或包含 ByteString 值的对象字面量。
- body: 请求的 body 信息:可能是一个 Blob、BufferSource、FormData、URLSearchParams 或者 USVString 对象。注意 GET 或 HEAD 方法的请求不能包含 body 信息。
- mode: 请求的模式,如 cors、no-cors 或者 same-origin。
- credentials: 请求的 credentials,如 omit、same-origin 或者 include。为了在当前域名内自动发送 cookie,必须提供这个选项,从 Chrome 50 开始,这个属性也可以接受- FederatedCredential (en-US) 实例或是一个 PasswordCredential (en-US) 实例。
- cache: 请求的 cache 模式:default、 no-store、 reload 、 no-cache、 force-cache 或者 only-if-cached。
- redirect: 可用的 redirect 模式:follow (自动重定向), error (如果产生重定向将自动终止并且抛出一个错误),或者 manual (手动处理重定向)。在 Chrome 中默认使用 follow(Chrome 47 之前的默认值是 manual)。
- referrer: 一个 USVString 可以是 no-referrer、client 或一个 URL。默认是 client。
- referrerPolicy: 指定了 HTTP 头部 referer 字段的值。可能为以下值之一:no-referrer、 no-referrer-when-downgrade、origin、origin-when-cross-origin、 unsafe-url。
- integrity: 包括请求的 subresource integrity 值(例如: sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=)。
注意: body 可读流,只能读一次
参考资料:
mdn web docs
axios中文文档