常用的三种请求方式ajax,axios,fetch

简介: 常用的三种请求方式ajax,axios,fetch

ajax常规用法



$.ajax({
    url: "https://www.api.com/api/xxx",  //ajax请求地址
    cache: true,// 默认true,dataType 为 script 和 jsonp 时默认为 false。设置为 false 将不缓存此页面
    type: "GET",//请求方式 "POST" 或 "GET", 默认为 "GET"。注意:其它 HTTP 请求方法,如 PUT 和 DELETE 也可以使用,但仅部分浏览器支持。
    dataType: "json",    //根据返回数据类型可以有这些类型可选:xml html script json jsonp text
    timeout:Number //设置请求超时时间(毫秒), 此设置将覆盖全局设置。
    //发送到服务器的数据,可以直接传对象{a:0,b:1},如果是get请求会自动拼接到url后面,如:&a=0&b=1
    //如果为数组,jQuery 将自动为不同值对应同一个名称。如 {foo:["bar1", "bar2"]} 转换为 "&foo=bar1&foo=bar2"。
    data: {},
    //默认true设置下,所有请求均为异步请求。如果需要发送同步请求,请将此选项设置为 false。注意,同步请求将锁住浏览器,用户其它操作必须等待请求完成才可以执行。
    async: true,
    //发送请求前可修改 XMLHttpRequest 对象的函数。
    //XMLHttpRequest 对象是唯一的参数。这是一个 Ajax 事件。
    //如果返回false可以取消本次ajax请求,也能设置一些http协议的header头信息。
    beforeSend:function(xhr){
        // 也可以禁用按钮防止重复提交
        $("#submit").attr({ disabled: "disabled" });
    },
    //context这个对象用于设置ajax相关回调函数的上下文。也就是说,让回调函数内this指向这个对象(如果不设定这个参数,那么this就指向调用本次AJAX请求时传递的options参数)。
    //比如指定一个DOM元素作为context参数,这样就设置了success回调函数的上下文为这个DOM元素。
    context: document.body,
    //请求成功后的回调函数
    success: function(data,textStatus){
        //this 调用本次AJAX请求时传递的options参数 ,如果设置context来改变了this,那这里的this就是改变过的
    },
    //请求失败时调用此函数。有以下三个参数:XMLHttpRequest 对象、错误信息、(可选)捕获的异常对象。
    //如果发生了错误,错误信息(第二个参数)除了得到null之外,还可能是"timeout", "error", "notmodified" 和 "parsererror"。
    error:function(XMLHttpRequest, textStatus, errorThrown){
        // 通常 textStatus 和 errorThrown 之中
        // 只有一个会包含信息
        // this 调用本次AJAX请求时传递的options参数
    },
    //请求完成后回调函数 (请求成功或失败之后均调用)。参数: XMLHttpRequest 对象和一个描述成功请求类型的字符串
    complete:function(XMLHttpRequest, textStatus) {
        //this 调用本次AJAX请求时传递的options参数
    },
    //一组数值的HTTP代码和函数对象,当响应时调用了相应的代码。例如,如果响应状态是404,将触发以下警报:
    statusCode:{
        404:function(){
            alert('404,页面不存在');
        }
    }
});


ajax.post



$.ajax({
    type: "POST",
    url: "https://www.api.com/api/xxx",
    dataType:'json',
    data: {id:1},//也可以是字符串链接"id=1",建议用对象
    success: function(data){
        console.log("返回的数据: " + data );
    }
});
或者
$.post("https://www.api.com/api/xxx",{id:1},function(data){
    console.log("返回的数据: " + data );
},'json');


ajax.get



$.ajax({
    type: "GET",
    url: "https://www.api.com/api/xxx",
    dataType:'json',
    data: {id:1001},//也可以是字符串链接"id=1001",建议用对象
    success: function(data){
        console.log("返回的数据: " + data );
    }
});
或者
$.get("https://www.api.com/api/xxx",{id:1},function(data){
    console.log("返回的数据: " + data );
},'json');
ajax.form
 $("form").on("submit",function(){
    var url = this.action;   // 可以直接取到表单的action
    var formData = $(this).serialize(); // 序列化表单数据
    $.post(url,formData,function(data){
        //返回成功,可以做一个其他事情
        console.log(data);
    },'json');
    //阻止表单默认提交行为
    return false
})


ajax.done



ajax请求成功通常是使用回调的方式处理返回数据,其实jquery中也可以使用连写方式而不是回调的方式


// 该参数可以是一个函数或一个函数的数组。当延迟成功时,done中函数被调用,回调执行是依照他们添加的顺序
$.get("https://www.api.com/api/xxx",{id:1}).done(function() {
    // 返回成功
}).fail(function(){
    // 处理失败;
});


ajax.then



$.get("https://www.api.com/api/xxx",{id:1}).then( 
    function(){ 
        //返回成功
    }, 
    function(){ 
       // 处理失败;
    }
);


ajax.when



两个全部请求成功才会执行回调, 否则就是失败,类似于Promise.all


$.when($.ajax("p1.php"), $.ajax("p2.php"))
.then(
    function(){ 
        //两个全部请求成功,才执行
    }, 
    function(){ 
        //任何一个执行失败
    }
);


ajax.获取文件



$.getScript():jQuery提供了此方法来直接加载js文件,与加载一个HTML片段一样简单方便,并且不需要对JavaScript文件进行处理,JavaScript文件会自动执行


$.getJSON('test.json', function(data)  {
    // 获取文件成功的回调   
});


ajax.load



load() 方法通过 AJAX 请求从服务器加载数据,并把返回的数据放置到指定的元素中


$('#result').load('ajax/test.html', function() {
    alert('Load was performed.');
});


//.load() 方法,与 $.get() 不同,允许我们规定要插入的远程文档的某个部分。这一点是通过 url 参数的特殊语法实现的。如果该字符串中包含一个或多个空格,紧接第一个空格的字符串则是决定所加载内容的 jQuery 选择器

// 如果test.html接口返回的是个html,则会插入到#container元素中

$('#result').load('ajax/test.html #container');


Axios



特性


  • 从浏览器中创建 XMLHttpRequest
  • 从 node.js 发出 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求和响应数据
  • 取消请求
  • 自动转换JSON数据
  • 客户端支持防止 CSRF/XSRF


API


  • 全局
  • axios.request(config)最终http请求都是执行这个方法
  • axios(config)和axios.request()等价
  • axios(url[, config])axios(config)快捷方式
  • axios.[METHODS](url, config)axios(config)快捷方式
  • 自定义实例
  • axios.create(config)自定义配置,创建实例instance。调用方式和axios方法一致
  • 拦截器
  • axios.interceptors.request.use
  • axios.interceptors.response.use


常见用法


配置优先级:lib/default.js中的库默认值 -->实例的config属性--> 请求的config参数


// 全局调用
   axios({
     method:'get',
     url:'https://www.api.com/api/xxx',
     field: 123
   }) // axios(config)
   axios('http://bit.ly/2mTM3nY', {field: 123}) // axios(url[, config])
   axios.get('http://bit.ly/2mTM3nY', {field: 123}) // axios.[METHODS](url, config)
   // 自定义实例调用
   const instance = axios.create({
     baseURL: 'https://www.api.com/api/xxx'
   });
   instance({
     method:'get',
     url:'2mTM3nY',
     field: 123
   }) // instance(config)
   instance.get('2mTM3nY', {field: 123}) // instance.[METHODS](url, config)


为何axios有如此多使用方式



源码在lib/default.js中
function createInstance(defaultConfig) {
      var context = new Axios(defaultConfig);
      // instance指向了request方法,且上下文指向context
      // instance(config) = Axios.prototype.request(config)
      var instance = bind(Axios.prototype.request, context);
      // 把Axios.prototype上的方法扩展到instance对象上
      // 这样 instance 就有了 get、post、put等METHOD方法
      // 同时指定上下文为context,这样执行Axios原型链上的方法时,this会指向context
      utils.extend(instance, Axios.prototype, context);
      // 把context对象上的自身属性和方法扩展到instance上
      utils.extend(instance, context);
      return instance;
    }
    // 导出时就创建一个默认实例,所以可以通过axios(config)发出请求
    var axios = createInstance(defaults);
    axios.Axios = Axios;
    // 工厂模式创建axios实例,其实最终都是调用createInstance方法。
    // 所以实例调用方式和全局axios调用方式相同。instance(config) = axios(config)
    axios.create = function create(instanceConfig) {
      return createInstance(mergeConfig(axios.defaults, instanceConfig));
    };
    module.exports = axios;
    module.exports.default = axios; // 允许在ts中导入


重点是createInstance方法,该方法拿到一个Function,该Function指向请求入口Axios.prototype.request,并且该Function还继承了Axios.prototype的每个方法,并且上下文指向同一个对象context。axios包默认导出是该Function,而自定义实例axios.create是一个工厂模式,最终都调用createInstance方法。


整体流程



请求流程实质上无非就是输入和输出,输入request config配置(如url、method、data等),输出最终的response data数据


中间涉及到较多的数据预处理,如根据data数据类型(如JSON),设置Content-Type: json头信息;再如根据响应的数据类型,默认转换为json格式。这些预处理需要axios库自动完成,同时也要暴露出相关配置给开发者,以此实现开发者自定义预处理。


Axios通过拦截者(Interceptors)来实现上面说的数据预处理,具体通过使用chain链式来逐一插入处理逻辑。默认情况下,先拿到此次请求的config配置,把config作为参数,传递到dispatchRequest方法中,该方法会根据当前环境(Browser/Node)来调用不同的adapter发送请求,以此获得最终的response data。同时Axios还允许使用request/response Interceptors进行请求前和响应后的自定义处理,其实质是将预处理函数,插入chain数组中,再统一按照顺序逐步执行预处理方法(Promise保证顺序)。


Axios类是核心内容,该类request方法是所有请求的开始入口。


源码在lib/core/Axios.js:
Axios.prototype.request = function request(config) {
  // 1. 允许 axios('url'[, config]) = axios(config)
  if (typeof config === 'string') {
    config = arguments[1] || {};
    config.url = arguments[0];
  } else {
    config = config || {};
  }
  // 配置文件合并策略优先级
  config = mergeConfig(this.defaults, config);
  config.method = config.method ? config.method.toLowerCase() : 'get';
  // 2. 定义拦截器中间件钩子
  // dispatchRequest是真正开始下发请求,执行config中设置的adapter方法
  var chain = [dispatchRequest, undefined];
  var promise = Promise.resolve(config);
  // 添加请求前钩子
  this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
    chain.unshift(interceptor.fulfilled, interceptor.rejected);
  });
  // 添加请求后钩子
  this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {
    chain.push(interceptor.fulfilled, interceptor.rejected);
  });
  // 3. chain链关键代码,promise链路传递下去
  while (chain.length) {
    promise = promise.then(chain.shift(), chain.shift());
  }
  return promise;
};
// 提供对request方法的METHOD快捷方式,实质都是调用Axios.prototype.request方法
// axios.get(url, config) = axios(config)
utils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {
  Axios.prototype[method] = function(url, config) {
    return this.request(utils.merge(config || {}, {
      method: method,
      url: url
    }));
  };
});
utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
  Axios.prototype[method] = function(url, data, config) {
    return this.request(utils.merge(config || {}, {
      method: method,
      url: url,
      data: data
    }));
  };
});


如何使用



请看我发表一篇《vue+axios+promise实际开发用法》,详细介绍具体用法


fetch


Fetch API 是近年来被提及将要取代XHR的技术新标准,是一个 HTML5 的 API。

Fetch 并不是XHR的升级版本,而是从一个全新的角度来思考的一种设计。Fetch 是基于 Promise 语法结构,而且它的设计足够低阶,这表示它可以在实际需求中进行更多的弹性设计。对于XHR所提供的能力来说,Fetch 已经足够取代XHR,并且提供了更多拓展的可能性。


基本用法


// 获取 some.json 资源  
fetch('some.json')  
 .then(function(response) {  
    return response.json();  
 })  
 .then(function(data) {  
    console.log('data', data);  
 })  
 .catch(function(error) {  
    console.log('Fetch Error: ', error);  
 });  
// 采用ES2016的 async/await 语法  
async function() {  
try {  
    const response = await fetch('some.json');  
    const data = response.json();  
    console.log('data', data);  
 } catch (error) {  
    console.log('Fetch Error: ', error)  
 }  
}


fetch.Post请求


fetch('https://www.api.com/api/xxx', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
    },
    body: 'a=1&b=2',
}).then(resp => resp.json()).then(resp => {
    console.log(resp)
});


fetch.Get请求


fetch('https://www.api.com/api/xxx?location=北京&key=bc08513d63c749aab3761f77d74fe820',{
    method:'GET'
}) // 返回一个Promise对象
.then((res)=>{
    return res.json();
})
.then((res)=>{
    console.log(res) // res是最终的结果
})


fetch请求网页


fetch('https://www.api.com/api/xxx')
    .then(response => response.text())
    .then(data => console.log(data));


自定义header


var headers = new Headers({
    "Content-Type": "text/plain",
    "X-Custom-Header": "aaabbbccc",
});
var formData = new FormData();
formData.append('name', 'lxa');
formData.append('file', someFile);
var config = {
    credentials: 'include', // 支持cookie
    headers: headers, // 自定义头部
    method: 'POST', // post方式请求
    body: formData // post请求携带的内容
};
fetch('https://www.api.com/api/xxx', config)
    .then(response => response.json())
    .then(data => console.log(data));
// 或者这样添加头部
var content = "Hello World";
var myHeaders = new Headers();
myHeaders.append("Content-Type", "text/plain");
myHeaders.append("Content-Length", content.length.toString());
myHeaders.append("X-Custom-Header", "ProcessThisImmediately");


fetch其他参数


  • method: 请求的方法,例如:GET,POST
  • headers: 请求头部信息,可以是一个简单的对象,也可以是 Headers 类实例化的一个对象。
  • body: 需要发送的信息内容,可以是Blob,BufferSource,FormData,URLSearchParams或者USVString。注意,GET,HEAD方法不能包含body。
  • mode: 请求模式,分别有cors,no-cors,same-origin,navigate这几个可选值。
  • cors: 允许跨域,要求响应中Acess-Control-Allow-Origin这样的头部表示允许跨域。
  • no-cors: 只允许使用HEAD,GET,POST方法。
  • same-origin: 只允许同源请求,否则直接报错。
  • navigate: 支持页面导航。
  • credentials: 表示是否发送cookie,有三个选项
  • omit: 不发送cookie
  • same-origin: 仅在同源时发送cookie
  • include: 发送cookie
  • cache: 表示处理缓存的策略。
  • redirect: 表示发生重定向时,有三个选项
  • follow: 跟随。
  • error: 发生错误。
  • manual: 需要用户手动跟随。
  • integrity: 包含一个用于验证资资源完整性的字符串


var URL = 'https://www.api.com/api/xxx';  
// 实例化 Headers  
var headers = new Headers({  
    "Content-Type": "text/plain",  
    "Content-Length": content.length.toString(),  
    "X-Custom-Header": "ProcessThisImmediately",  
});  
var getReq = new Request(URL, {method: 'GET', headers: headers });  
fetch(getReq).then(function(response) {  
    return response.json();  
}).catch(function(error) {  
    console.log('Fetch Error: ', error);  
});


相关文章
|
1月前
|
XML 前端开发 JavaScript
|
13天前
|
JSON 前端开发 JavaScript
Proxy + Fetch 实现类似于 axios 的基础 API
本项目通过 Proxy 和 Fetch 技术实现了一个类似 axios 的基础 API,支持请求拦截、响应处理等功能,简化了前端网络请求的开发流程,提升了代码的可维护性和扩展性。
|
2月前
|
JSON JavaScript 前端开发
《进阶篇第6章:vue中的ajax》包括回顾发送ajax请求方式、vue-cli脚手架配置代理服务器、vue-resource
《进阶篇第6章:vue中的ajax》包括回顾发送ajax请求方式、vue-cli脚手架配置代理服务器、vue-resource
59 22
|
1月前
|
前端开发 API 开发者
Python Web开发者必看!AJAX、Fetch API实战技巧,让前后端交互如丝般顺滑!
在Web开发中,前后端的高效交互是提升用户体验的关键。本文通过一个基于Flask框架的博客系统实战案例,详细介绍了如何使用AJAX和Fetch API实现不刷新页面查看评论的功能。从后端路由设置到前端请求处理,全面展示了这两种技术的应用技巧,帮助Python Web开发者提升项目质量和开发效率。
44 1
|
2月前
|
前端开发 JavaScript
回顾前端页面发送ajax请求方式
回顾前端页面发送ajax请求方式
38 18
|
1月前
|
JavaScript 前端开发 Java
SpringBoot项目的html页面使用axios进行get post请求
SpringBoot项目的html页面使用axios进行get post请求
47 2
|
21天前
|
JavaScript 前端开发 Java
SpringBoot项目的html页面使用axios进行get post请求
SpringBoot项目的html页面使用axios进行get post请求
34 0
|
2月前
|
前端开发 JavaScript Java
第6章:Vue中的ajax(包含:回顾发送ajax请求方式、vue-cli脚手架配置代理服务器)
第6章:Vue中的ajax(包含:回顾发送ajax请求方式、vue-cli脚手架配置代理服务器)
81 4
|
2月前
|
Python
axios的get请求传入数组参数
【10月更文挑战第11天】 当使用 `axios` 发送包含数组参数的 GET 请求时,默认的序列化方式可能与后端(如 Django)不兼容,导致无法正确获取数组参数。解决方案是通过 `paramsSerializer` 指定自定义序列化函数,或使用 `qs` 库来格式化数组参数,确保前后端一致。示例代码展示了如何使用 `qs` 库设置 `arrayFormat` 为 `"repeat"`,以符合 Django 的解析要求。
66 2
|
2月前
|
JSON JavaScript 前端开发
axios的post请求,数据为什么要用qs处理?什么时候不用?
axios的post请求,数据为什么要用qs处理?什么时候不用?