JS: Axios 和 Fetch

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){}
})

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值