axios浏览器异步请求方法封装 XMLHttpRequest
axios学习笔记defaults(浏览器端异步请求处理方式)
浏览器异步请求方法封装,主要使用XMLHttpRequest
lib/adapters/xhr.js
//入口
var utils = require('./../utils');
var settle = require('./../core/settle');
var buildURL = require('./../heapers/buildURL');
var buildFullPath = require('./../core/buildFullPath');
var parseHeaders = require('./../heapers/parseHeaders');
var isURLSameOrigin = require('./../helpers/isURLSameOrigin');
var createError = require('./../core/createError')
settle方法
lib/core/settle.js
//验证请求返回结果,成功走resolve,失败走reject
var createError = require('./createError')
function seetle(resolve, reject, response){//resolve,reject为promise中参数
var validateStatus = response.config.validateStatus;//获取默认的状态码校验方法
//状态码验证通过
if(!validateStatus || validateStatus(response.staus)){
resolve(data)
} else {
reject(createError(
'request failed with status code' + response.status,//响应状态码
response.config,//响应配置项
null,
response.request,
response,
))
}
}
createError方法
lib/core/createError.js
//new一个包含message的error对象
var enhanceError = require('./enchanceError')
function createError(message, config, code, request, response){
var error = new Error(message);//实例化一个error对象
//给error对象添加请求的各种信息
return enhanceError(error, config, code, request, response)
}
enchanceError方法
lib/core/enhanceError.js
//将请求出错返回的相关信息全都挂到error对象上,然后抛出,方便定位出错信息
function enchanceRrror(error, config, code, request, response){
error.config = config;
if(code){
error.code = code
}
error.request = request;
error.response = response;
error.isAxiosError = true;
return error.toJSON = function(){
return {
// Standard(标准浏览器)
message: this.message,
name: this.name,
// Microsoft(ie可用)
description: this.description,
number: this.number,
// Mozilla(火狐)
fileName: this.fileName,
lineNumber: this.lineNumber,
columnNumber: this.columnNumber,
stack: this.stack,
// Axios
config: this.config,
code: this.code
}
}
return error
}
buildURL方法
lib/heapers/buildURL.js
//绑定get请求中的parmas到url上
function bindURL(url, params, paramsSerializer) {
if(!params) return url;
var serializedParams;
if(paramsSerialized) {
serializedParams = paramsSerializer(params);
} else if(utils.isURLSerarchParams(params)) {
serializedParams = params.toString();
} else {
var pats = [];
utils.forEach(params, function serialze(val, key) {
if(val == null || typeof val == 'undefind'){
return;
}
//将val变成数组
if(utils.isArray(val)){
key = key+'[]';
}else{
val = [val];
}
})
utils.forEach(val, function parseValue(v) {
if (utils.isDate(v)) {
v = v.toISOString();
} else if (utils.isObject(v)) {
v = JSON.stringify(v);
}
parts.push(encode(key) + '=' + encode(v));
});
serializedParams = pats.join(&);
}
if(serializedParams) {
var hashmarkIndex = url.indexOf('#');
if(hashmarkIndex != -1) {
url = url.slice(0, hashmarkIndex);
}
url += (url.indexOf('?') == -1? '?' : '&') + serializedParams;
}
return url;
}
buildFullPath
lib/core/buildFullPath.js
//获得完整的url
function buildFullPath(baseUrl, requestUrl) {
//存在baseUrl 且requestUrl不是完整的url
if(baseUrl && !isAbsoluteURL(requestUrl)){
//合并url
return combine(baseUrl, requestUrl)
}
return requestUrl;
}
xhrAdapter方法
lib/adapter/xhr.js
//浏览器异步请求基本适配器
function xhrAdapter(config) {
return new Promise(fuction dispatchXhrRequest(resove, reject){
var requestData = config.data;
var requestHeaders = config.headers;
//如果请求参数是formData类型, 删除用户自定义的请求参数格式Content-Type
if(utils.isFormData(requestData)){
delete requestHedeaders['Content-Type'];
}
//XMLHttpRequest 对象用户与后台服务器交换数据,所有现代浏览器都支持此对象
var request = new XMLHttpRequest()
//加auth信息
if(config.auth){
var username = config.auth.username || '';
var password = config.auth.password || '';
requestHeaders.Authorization = 'Basic' + btoa(username + ':' + password);
}
var fullPath = buildFullUrl(config.baseURL, config.url);
request.open(config.methods.toUpperCase, buildUrl(fullPath, config.params, config.paramsSerialze), true);
request.timeout = config.timeout;
request.onreadystatechange = function handleload() {
if(!request || request.readyState !== 4) {
return null;
}
if(request.status == 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)){
return null;
}
//获取所有请求头信息
var responseHeaders = 'getAllResponseHeaders' in request ? parseHeaders(requerst.getAllResponseHeaders()) : null;
//如果接受数据类型为text类型,返回responseText 否则返回request.response
var responseData = !config.responseType || config.responseType === 'text' ? request.responseText : request.response;
var response = {
data: responseData,
status: request.status,//响应中数字状态码,请求完成前status为0.如果XMLHttpRequest出错也为0
statusText: request.statusText,
config: config,
request: request,
}
//结果自定义验证
settle(resolve, reject, response)
//清除 request
request = null;
}
//请求被中止时处理
request.onabort = function handleAbort() {
if(!request) return;
reject(createError('Request Abort', config, 'ECONNABORTED', request))
request = null;
}
request.onerror = function handleError() {
reject(createError('Network Error', config, null, request))
//清除请求实例
request = null
}
request.ontimeout = function handleTimeout() {
var timeoutErrorMessage = 'timeout of ' + config.timeout + 'ms exceeded';
if(config.timeoutErrorMessage) {
timeoutErrorMessage = config.timeoutErrorMessage
}
reject(createError(timeoutErrorMessage, config, 'ECONNABORTED', request))
request = null
}
<!-- 现代浏览器添加xsrfValue -->
if(utils.isStandarBrowserEvn()){
<!-- cookeis中有3个方法,write read remove 写 读 删除 -->
var cookies = requset('./../headers/cookies');
var xsrfValue = (config.withCredentials || isURLSameOrigin(fullPath)) && config.xsrfCookieName ? cookie.read(config.xsrfCookieName) : undefined;
<!-- 将xsrfCookieName写道请求头里面 -->
if(xsrfValue) {
requestHeaders[config.xsrfCookieName] = xsrfValue;
}
}
<!-- add heders to the request -->
if('setReuqetHeaders' in request) {
utils.forEach(requestHeaders, function setRequestHeader(val, key) {
//如果没有参数,content-type 不需要设置
if(typeof requestData === 'undefined' && key.toLowerCase()=='content-type'){
delete requestHeaders[key];
} else {
request.setRequestHeaders(key, val);
}
})
}
<!-- 设置跨域请求的withCredentials 指定跨域Access-Control请求是否应该带有授权信息 例如cookie或者authorization头 -->
if(config.withCredentials) {
request.withCredentials = true;
}
<!-- 设置浏览器期望接受返回数据的类型 对应resposne中的Content-Type-->
if(config.responseType) {
try {
request.responseType = config.responseType
} catch (e) {
if(config.responseType !== 'json') {
throw e;
}
}
}
<!-- 处理进度。例如下载文件需要 监听进度事件-->
if(typeof config.onDownloadProgress === 'function') {
request.addEventListenner('progress', config.onDownloadProgress)
}
<!-- 不是所有的的浏览器都支持上传事件 upload -->
if(typeof config.onUploadProgress == 'function' && request.upload){
request.addEventListenner('progress', config.onUploadProgress)
}
<!-- cancleToken axios中取消请求 -->
if(config.cancleToken){
//如果请求返回成功,则打断request
config.cancleToken.promise.then(function onCancled(cancale){
if(!request) return;
request.abort(); 打断已经发出的请求
reject(cancle)
request = null
})
}
if(requestData === undefined){
requestData = null;
}
//发送数据
rquest.send(requestData)
})
}
总结
request 实例上的方法和事件 var request = new XMLHttpRequest();
方法
request.abort() 如果请求已被发送,则立刻中止请求
request.getAllResponseHeaders() 以字符串的形式返回所有用CRLF分割的响应头,如果没有收到响应,则返回null
request.getResponseHeaders() 返回包含指定响应头的字符串,如果响应头没收到或者不存在该报头,则返回null
request.open() 初始化一个请求,该方法只能再javascript中使用,若在native code 中初始化请求,请使用openRequest()
request.overrideMimeType() 重写服务器返回的MIME类型
request.send() 发送请求,如果请求时异步的,那么该放大将在请求发送后立即返回
request.setRequestHeader() 设置http请求头,必须在open()之后send()之前调用setRequestHeader()方法
事件
abort 也可以使用onabort属性 当request被停止时触发
error 也可以使用onerror属性 当request遇到错误时触发
load 也可以使用onload属性 当request请求完成时触发
timeout 也可以使用ontimeout属性 预设时间内没有接受到响应时触发
progress 进度事件 request.addEventListener('progress', function(e) {})
...
axios浏览器异步请求方法封装 XMLHttpRequest的更多相关文章
- 基于promise对小程序http请求方法封装
原因是我不想每次请求都复制粘贴那么长的请求地址,所以我把前边那一坨请求地址作为基础地址,只传后台给的路由就ok,而且,并不是每次请求都要显示正在加载,这对小程序体验很差,所以,我加了个形参,用来判断是 ...
- vue 使用 axios 时 post 请求方法传参无法发送至后台
axios 时 post 请求方法传参无法发送至后台报错如下 Response to preflight request doesn't pass access control check: No ' ...
- 通用ajax请求方法封装,兼容主流浏览器
ajax简单介绍 没有AJAX会怎么样?普通的ASP.Net每次运行服务端方法的时候都要刷新当前页面. 假设没有AJAX,在youku看视频的过程中假设点击了"顶.踩".评论.评论 ...
- axios请求方法封装.
axios的使用上一般封装好对应的方法,ES6导出,直接调用,消息通知使用了ElementUI的Message组件. 这是一个封装了axios的Rest风格的工具类,包扩常用的POST,GET,PUT ...
- vue-cli配置axios,并基于axios进行后台请求函数封装
文章https://www.cnblogs.com/XHappyness/p/7677153.html已经对axios配置进行了说明,后台请求时可直接this.$axios直接进行.这里的缺点是后端请 ...
- axios的post请求方法---以Vue示例
Axios向后端提交数据的参数格式是json,而并非用的是form传参,post表单请求提交时,使用的Content-Type是application/x-www-form-urlencoded,而使 ...
- axios & fetch 异步请求
// 一.创建实例 const request = axios.create({ baseURL: "http://kg.zhaodashen.cn/v2", headers: { ...
- vue中的表单异步校验方法封装
在vue项目的开发中,表单的验证必不可少,在开发的过程中,用的是vue+iview的一套,我们知道iview的表单验证是基于async-validator,对于async-validator不熟悉的可 ...
- Java多线程开发系列之五:Springboot 中异步请求方法的使用
Springboot 中异步线程的使用在过往的后台开发中,我们往往使用java自带的线程或线程池,来进行异步的调用.这对于效果来说没什么,甚至可以让开发人员对底层的状况更清晰,但是对于代码的易读性和可 ...
随机推荐
- VS2010 报错该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
尤其代码是从linux平台复制过来: 报错如图: 更有甚者基本函数都报错: 当下检查发现if else break case等基本函数并无问题时,报错行数明显不一致等一定要注意文档编码格式, 最简单的 ...
- i春秋-第三届“百越杯”福建省高校网络空间安全大赛-Do you know upload?
进去提示有提示文件包含漏洞 拿到源码发现这里上传验证只有MIME验证 可直接抓包改 image/gif 绕过 接下来就是这次学到的点了 菜刀连接过后怎么都找不到flag文件,但是这里找到了数据库配置文 ...
- GCN实现3
参考 : 首先看两篇论文,大概了解一下原理性的东西: GRAPH CONVOLUTIONAL NETWORKS THOMAS KIPF, 30 SEPTEMBER 2016 http://tkipf. ...
- F5部署SSL证书
查找中间证书 为了保证可以兼容所有浏览器,我们必须在服务器上安装中间证书,请到 中间证书下载工具,输入您的Server.cer,然后下载中间证书,请将中间证书保存为Chain.cer. 证书文件的上传 ...
- springcloud学习之路: (三) springcloud集成Zuul网关
网关就是做一下过滤或拦截操作 让我们的服务更加安全 用户访问我们服务的时候就要先通过网关 然后再由网关转发到我们的微服务 1. 新建一个网关服务Module 2. 依然选择springboot工程 3 ...
- eclipse springboot工程打war包方法及在Tomcat中运行的方法
一, eclipse springboot打war包 1. 配置pom.xml文件 <packaging>war</packaging> <!-- 配置servlet,打 ...
- 001-k8s集群的安装
k8s集群的安装 1.实验描述 通过搭建 K8S 的集群,来学习对容器的编排 2.实验环境 [你可能需要][CentOS 7 搭建模板机]点我快速打开文章 [你可能需要][VMware 从模板机快速克 ...
- Nginx类
nginx常见错误页面有哪些?对于其解决方法是什么? 404 bad request 请求失败,请求所希望得到的资源未被在服务器上发现.没有信息能够告诉用户这个状况到底是暂时的还是永久的.假如服务器知 ...
- css 序
盒模型 1.属性:width :内容的宽度 书写内容的宽度 height:内容的高度 书写内容的宽度 padding:内边框 内容到边框的距离 可以有 background-color borde ...
- Linux 找文件
最简单的可以使用 find find . -name "libxxx.so" 还可以使用 locate libxxx.so