Axios
基于XMLHttpRequest对象,使用 Promise封装,使用时需要导入axios.js。
CDN地址:https://unpkg.com/axios/dist/axios.js,压缩版 https://unpkg.com/axios/dist/axios.min.js
Fetch
浏览器原生API,使用Promise封装,在尚未支持ES6语法的浏览器中使用时需要导入es6-promise.js。
CDN地址:https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.js,自动替换版 https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.js,压缩版 https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.min.js,自动替换压缩版https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.min.js。
GET语法
//Axios
axios.get('http://127.0.0.0:80/cors', {
params: {a: 'a',b: 'b'}
}).then(function (response) {
console.log(response);
}).catch(function (error) {
console.log(error);
});
//或
axios('http://127.0.0.0:80/cors?a=a&b=b').then(function (response) {
console.log(response);
}).catch(function (error) {
console.log(error);
});
//Fetch
fetch('http://127.0.0.1:80/cors').then(function(response) {
return response.json(); //利用链式操作先处理数据
}).then(function(data) {
console.log(data);
}).catch(function(err) {
console.log(err);
});
POST语法
//Axios
axios.post('/cors', { a: 'a',b: 'b'}).then(function (response) {
console.log(response);
}).catch(function (error) {
console.log(error);
});
//Fetch
fetch('http://127.0.0.1:80/cors', {
method: 'POST',
body: JSON.stringify({ a: 'a', b: 'b'}),
headers: new Headers({
'Content-Type': 'application/json'
})
}).then(response => response.json())
.then(data => console.log(data ))
.catch(err => console.error(err ))
通用语法
//Axios
axios({
baseURL: 'http://127.0.0.1:80', //baseURL将自动加在url前面,除非url是绝对路径
url: '/cors',
method: 'post', // 默认get
// URL携带的参数(GET,HEAD请求发送的数据在这里设置),必须是plain object或URLSearchParams
params: {
ID: 12345
},
// 对URL携带的参数进行序列化处理
paramsSerializer: function(params) {
return Qs.stringify(params, {arrayFormat: 'brackets'})
// Qs方法需要引入https://www.npmjs.com/package/qs,
// 也可以使用jQuery的序列化方法 http://api.jquery.com/jquery.param/
},
// 发送到服务端的数据(仅'PUT', 'POST', 'PATCH'请求使用)
data: {
firstName: 'Fred'
},
//如果没有设置 transformRequest,则必须是以下类型:
// - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
// - 浏览器专属:FormData, File, Blob
// - Node 专属: Stream
// 对将要发送到服务端的数据进行处理(仅'PUT', 'POST', 'PATCH'请求使用)
transformRequest: [function (data) {
// 对 data 进行任意转换处理
return data;
//数组中的函数必须返回一个string、ArrayBuffer 或 Stream(node)
}],
// 超时时间
timeout: 5000,
//HTTP请求头设置
headers: {
'X-Requested-With': 'XMLHttpRequest',
'Content-Type' : 'application/x-www-form-urlencoded',
'Authorization' : YOUR_AUTH_TOKEN,
},
// 跨域请求是否携带cookie 默认false
withCredentials: false,
responseType: 'json', // 预期服务器响应的数据类型 默认的json,可选'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
maxContentLength: 2000, //响应内容的最大尺寸
//上传期间处理进度事件
onUploadProgress: function (progressEvent) {
// 对原生进度事件的处理
},
//下载期间处理进度事件
onDownloadProgress: function (progressEvent) {
// 对原生进度事件的处理
},
//配置返回的HTTP响应状态码处理函数,返回true触发resolve,返回false触发reject
validateStatus: function (status) {
return status >= 200 && status < 300; // 默认
},
// 对将要传递给then/catch的响应数据进行处理
transformResponse: [function (data) {
// 对 data 进行任意转换处理
return data;
}],
// 指定用于取消请求的 cancel token
cancelToken: new axios.CancelToken(function executor(cancel) {
// executor 函数接收一个 cancel 函数作为参数
axiosCancel = cancel;
}),
// 使用自定义处理请求函数
adapter: function (config) {
/* 返回一个 promise 并应用一个有效的响应 (查阅 [response docs](#response-api)) */
},
// 设置Authorization头,覆写掉现有的任意 headers 设置,使用 HTTP 基础验证,并提供凭据
auth: {
username: 'janedoe',
password: 's00pers3cret'
},
// 设置Proxy-Authorization头,覆写掉已有的通用 header 设置,使用代理
proxy: {
host: '127.0.0.1',
port: 9000,
auth: : {
username: 'mikeymike',
password: 'rapunz3l'
}
},
/* 定义 xsrf token 的值的cookie的名称
xsrfCookieName: 'XSRF-TOKEN', // default */
/* 定义承载 xsrf token 的值的 HTTP 头的名称
xsrfHeaderName: 'X-XSRF-TOKEN', // 默认的 */
/* 在 node.js 中 follow 的最大重定向数目,如果设置为0,将不会 follow 任何重定向
maxRedirects: 5, // 默认的 */
/* 在 node.js 中用于定义在执行 http 和 https 时使用的自定义代理。允许像这样配置选项:
httpAgent: new http.Agent({ keepAlive: true }),// `keepAlive` 默认false
httpsAgent: new https.Agent({ keepAlive: true }),*/
}).then(function(response) {
console.log(response.data);
console.log(response.status);
console.log(response.statusText);
console.log(response.headers);
console.log(response.config);
//可以传递 reject 回调函数作为 then 的第二个参数,相当于catch的第一个参数
}).catch(function(error){
if (error.response) {
// 请求已发出,但服务器响应的状态码不在 2xx 范围内
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else {
// Something happened in setting up the request that triggered an Error
console.log('Error', error.message);
}
console.log(error.config);
})
//定义取消请求函数
var axiosCancel;
//自定义拦截器
//在请求之前拦截,类似beforeSend
var requestInterceptor = axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
config.data = JSON.stringify(config.data)
config.headers['Content-Type'] = 'application/x-www-form-urlencoded'
return config;
/*通过cancelToken取消请求
axiosCancel()*/
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
//在响应之前拦截,触发then/catch之前执行
var responseInterceptor = axios.interceptors.response.use(function(response) {
// 对响应数据做点什么
return response;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
//移除拦截器
axios.interceptors.request.eject(requestInterceptor );
axios.interceptors.response.eject(responseInterceptor );
//Fetch
fetch('http://127.0.0.1:80/cors', {
method: "POST",
mode: "cors", // 请求模式 默认same-origin(同源),可选no-cors(禁止跨域), cors(跨域),
/*
使用cors进行跨域请求时,服务端响应头中需要设置Access-Control-Allow-Origin为*或指定域来限制允许跨域的请求的来源,
除此之外,还可以设置Access-Control-Allow-Headers为"Authorization,Origin, X-Requested-With, Content-Type, Accept"等来限制允许跨域的请求头、
Access-Control-Allow-Methods为"GET,POST"等限制允许跨域的请求方式。
*/
cache: "no-cache", // 缓存设置 默认default, 可选no-cache, force-cache, only-if-cached, reload
credentials: "same-origin", // cookie设置 默认omit(不携带),可选include(可跨域携带), same-origin(同域携带)
headers: { // HTTP请求头设置
"Content-Type": "application/json; charset=utf-8", //发送到服务器的数据类型 "application/x-www-form-urlencoded",
"Accept": "application/json" // 预期从服务器接受的数据类型
},
body: JSON.stringify(data), // 发送到服务端的数据,数据格式要和header中的"Content-Type" 一致
}).then(response => { //即使该 HTTP 响应的状态码是 404 或 500。依然会触发resolve,但是会将 resolve 的返回值的 ok 属性设置为 false 。
response.json() // parses response to JSON
console.dir(response)
/*输出的响应数据格式如下,注意 response是一个完整的响应数据对象,其中body才是需要获取的数据本身,Header是一个响应头对象
{
body: ReadableStream
bodyUsed: false
headers: Headers
ok : false
redirected : false
status : 404
statusText : "Not Found"
type : "cors"
url : "http://127.0.0.1:80/cors"
__proto__ : Response
}*/
/*在处理时候需要通过判断 response.ok === true 或者 response.status >= 200 && response.status <= 300 来确认响应状态,当response.ok 为 fasle时,可以通过下面两种方法进如catch中:
1.throw new Error('something went wrong!')
2. return Promise.reject('something went wrong!')*/
}).catch(error=> { //仅当网络故障时或请求被阻止导致HTTP请求失败、运行时报错、主动触发reject方法时,才会标记为 reject。
error.json() // parses error to JSON
});
对比XMLHttpRequest (XHR)和 jQuery的ajax方法(基于XHR对象封装)
//XMLHttpRequest
//尝试创建XHR实例对象
var xhr = null
if (window.XMLHttpRequest) { // Chrome Mozilla Safari Edge IE7 IE7+
xhr = new XMLHttpRequest()
} else if (window.ActiveXObject) { // IE6 IE6-
try {
xhr = new ActiveXObject('Msxml2.XMLHTTP') // MSXML 3.0
} catch (e) {
try {
xhr = new ActiveXObject('Microsoft.XMLHTTP') // 骨灰
} catch (e) {
//骨灰都不如,用不了ajax
}
}
}
//成功创建的XHR实例对象
if (xhr) {
xhr.open('POST', 'http://127.0.0.1:80/cors', true)//创建请求
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')//设置请求头
xhr.setRequestHeader('Accept', 'application/json')
xhr.timeout = 5000
xhr.send('a=a&b=b')//发送请求
//xhr.send执行后,JS将继续执行当前EventLoop中后面的程序,当readyState改变时,会将回调函数添加到callbackQueue尾部
//绑定监听readyState改变的回调函数(当前readyState为0)
xhr.onreadystatechange = function(){
if(xhr.readyState === 1){// xhr.open方法调用后状态
//如果xhr.onloadstart绑定了回调函数将在此状态触发
}else if(xhr.readyState === 2){ // xhr.send方法调用后状态
// 将触发xhr.onloadstart绑定的回调函数
}else if(xhr.readyState === 3){ // 服务器数据开始接收状态
//如果xhr.onprogress绑定了回调函数将在此状态触发,回调函数默认传入ProgressEvent对象参数, 可通过 e.loaded/e.total 来计算加载资源的进度
}if (xhr.readyState === 4) {// 服务器响应完成后状态
// 判断HTTP响应状态码
if (xhr.status >= 200 || xhr.status < 300) {
console.log(xhr.responseText)
} else {
console.log('请求失败')
}
}
}
}
//jQuery ajax
var ajaxObj = $.ajax({
type:'POST',
url:'http://127.0.0.1:80/cors',
data:{a:'a',b:'b'},//发送至服务器的数据,jquery将自动将数据转换为指定格式字符串
contentType: "application/x-www-form-urlencoded", //发送至服务器的内容编码
dataType:'json',//预期服务器返回数据类型,'jsonp'时jquery将自动使用JSONP调用callback
crossDomain:true,//跨域设置 默认false
/*jsonp:'', 指定JSONP请求回调函数名,默认为'callback'
jsonpCallback:'',指定JSONP请求回调函数,不设置则jquery随机生成一个函数名*/
timeout:5000,
async:true, //是否同步,默认 true ,设为false会阻塞JS进程,等待请求完成后继续执行
cache:false, //是否缓存
beforeSend:function(xhr){
xhr.abort();
},
success:function(data){
console.log(data)
},
error:function(xhr, textStatus, err){
console.log(err)
},
complete:function(xhr, textStatus){}
})