jQuery是一个快速、简洁的JavaScript框架,是继Prototype以后又一个优秀的JavaScript代码库(_或JavaScript框架_)。jQuery设计的宗旨是“write Less,Do More”,即倡导写更少的代码,作更多的事情。它封装JavaScript经常使用的功能代码,提供一种简便的JavaScript设计模式,优化HTML文档操做、事件处理、动画设计和Ajax交互。做者我也是在2015年就开始用jQuery,那时候跟同事比看谁写的代码更短
如若看个jQuery源码的同窗,j应该知道jq是对原生XHR的封装,另外还增长了jsonp的支持,让ajax请求能够支持跨域请求,
可是要注意的是:jsonp请求本质不是XHR异步请求,就是请求了一个js文件,所以在浏览器的network面板中的xhr标签下看不到jsonp的跨域请求,可是在js标签下能看见,由于它利用src特性请求任何一个网站的资源。php
$.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({ 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({ 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');
$("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请求成功一般是使用回调的方式处理返回数据,其实jquery中也可使用连写方式而不是回调的方式html
// 该参数能够是一个函数或一个函数的数组。当延迟成功时,done中函数被调用,回调执行是依照他们添加的顺序 $.get("https://www.api.com/api/xxx",{id:1}).done(function() { // 返回成功 }).fail(function(){ // 处理失败; });
$.get("https://www.api.com/api/xxx",{id:1}).then( function(){ //返回成功 }, function(){ // 处理失败; } );
两个所有请求成功才会执行回调, 不然就是失败,相似于Promise.allvue
$.when($.ajax("p1.php"), $.ajax("p2.php")) .then( function(){ //两个所有请求成功,才执行 }, function(){ //任何一个执行失败 } );
$.getScript():jQuery提供了此方法来直接加载js文件,与加载一个HTML片断同样简单方便,而且不须要对JavaScript文件进行处理,JavaScript文件会自动执行node
$.getJSON('test.json', function(data) { // 获取文件成功的回调 });
load() 方法经过 AJAX 请求从服务器加载数据,并把返回的数据放置到指定的元素中jquery
$('#result').load('ajax/test.html', function() { alert('Load was performed.'); }); //.load() 方法,与 $.get() 不一样,容许咱们规定要插入的远程文档的某个部分。这一点是经过 url 参数的特殊语法实现的。若是该字符串中包含一个或多个空格,紧接第一个空格的字符串则是决定所加载内容的 jQuery 选择器 // 若是test.html接口返回的是个html,则会插入到#container元素中 $('#result').load('ajax/test.html #container');
特性ios
APIgit
全局github
axios.request(config)
最终http请求都是执行这个方法axios(config)
和axios.request()等价axios(url[, config])
axios(config)快捷方式axios.[METHODS](url, config)
axios(config)快捷方式自定义实例ajax
axios.create(config)
自定义配置,建立实例instance。调用方式和axios方法一致拦截器json
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)
源码在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 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('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('https://www.api.com/api/xxx?location=北京&key=bc08513d63c749aab3761f77d74fe820',{ method:'GET' }) // 返回一个Promise对象 .then((res)=>{ return res.json(); }) .then((res)=>{ console.log(res) // res是最终的结果 })
fetch('https://www.api.com/api/xxx') .then(response => response.text()) .then(data => console.log(data));
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");
GET
,POST
。Blob
,BufferSource
,FormData
,URLSearchParams
或者USVString
。注意,GET
,HEAD
方法不能包含body。mode: 请求模式,分别有cors
,no-cors
,same-origin
,navigate
这几个可选值。
Acess-Control-Allow-Origin
这样的头部表示容许跨域。HEAD
,GET
,POST
方法。credentials: 表示是否发送cookie
,有三个选项
cookie
。cookie
。cookie
。redirect: 表示发生重定向时,有三个选项
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); });