一、什么是网络请求,网路请求的类型
-
1.1 什么是网路请求,网路请求关心哪些内容
传入基本参数(url,请求方式) 请求参数、请求参数类型 设置请求头 获取响应的方式 获取响应头、响应状态、响应结果 异常处理 携带cookie设置 跨域请求
-
1.2网路请求的类型
同步请求 异步请求
二、同步请求的模式

三、异步请求的模式
四、当前流行的异步请求方案
axios、fetch、ajax
问题一:axios、fetch与ajax有什么区别?
主要区别是 axios、fetch请求后都支持Promise对象API
,ajax只能用回调函数。
- Ajax
Ajax被认为是(Asynchronous JavaScript and XML)的缩写。现在,允许浏览器与服务器通信而无须刷新当前页面的技术都被叫做Ajax。依赖的传输对象:XMLHttpRequest
ajax无需多言,如果想要更多了解,参考以下链接:ajax详解
- axios:
代码示例
axios({
method: 'post',
url: '/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
Vue2.0之后推荐大家用axios替换JQuery ajax,
- Axios本质上
也是对原生XHR的封装
,只不过它是Promise的实现版本
,符合最新的ES规范,它有以下几条特性: - 从 node.js 创建 http 请求
- 支持 Promise API
- 客户端支持防止CSRF
- 提供了一些并发请求的接口(重要,方便了很多的操作)
Axios既提供了并发的封装,也没有fetch的各种问题,而且体积也较小,推荐大家使用。axios-详解 axios-npm官网
1、Axios 是一个基于 promise 的 HTTP 库,支持promise所有的API
2、它可以拦截请求和响应
3、它可以转换请求数据和响应数据,并对响应回来的内容自动转换成 JSON类型的数据
4、安全性更高,客户端支持防御 XSRF
- axios请求方式
axios.request(config);
axios.get(url[,config]);
axios.delete(url[,config]);
axios.head(url[,config]);
axios.post(url[,data[,config]]);
axios.put(url[,data[,config]])
axios.patch(url[,data[,config]])
并发请求(concurrency),即是帮助处理并发请求的辅助函数
//iterable是一个可以迭代的参数如数组等
axios.all(iterable)
//callback要等到所有请求都完成才会执行
axios.spread(callback)
- fetch
示例
fetch(url).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
Fetch API 提供了一个 JavaScript接口,用于访问和操纵HTTP管道的部分,例如请求和响应。它还提供了一个全局 fetch()方法,该方法提供了一种简单,合理的方式来跨网络异步获取资源。
Fetch 优点主要有:
-
语法简洁,更加语义化
-
基于标准 Promise 实现,支持 async/await
-
同构方便,使用 isomorphic-fetch
不过原生支持率并不高,引入下面这些 polyfill 后可以完美支持 IE8+ :
-
由于 IE8 是 ES3,需要引入 ES5 的 polyfill: es5-shim, es5-sham
-
引入 Promise 的 polyfill: es6-promise
-
引入 fetch 探测库:fetch-detector
-
引入 fetch 的 polyfill: fetch-ie8
-
可选:如果你还使用了 jsonp,引入 fetch-jsonp
-
可选:开启 Babel 的 runtime 模式,现在就使用 async/await
问题二:Promise对象是什么?关于Promise对象的详细解析
Promise对象是ES6( ECMAScript 2015 )对于异步编程提供的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。
传统回调:
// 当参数a大于10且参数func2是一个方法时 执行func2
function func1(a, func2) {
if (a > 10 && typeof func2 == 'function') {
func2()
}
}
func2(11, function() {
console.log('this is a callback')
})
Promise对象改写:
function func1(a){
return new Promise((resolve,reject) => {
if(a > 10){
resolve(a)
}else{
reject(b)
}
})
};
func1('11').then(res => {
console.log('success');
}).catch(err => {
console.log('error');
})
Promise对象的两个特点:
1、对象的状态不受外界影响。
Promise对象有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。
只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
这也是Promise这个名字的由来,它的英语意思就是“承诺”
,表示其他手段无法改变。
2、一旦状态改变,就不会再变,任何时候都可以得到这个结果。
Promise对象的状态改变,只有两种可能:
从pending变为fulfilled和从pending变为rejected。
只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。
如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
Promise对象实例的两个参数,resolve 和 reject:
Promise构造函数接受一个函数作为参数,该函数的两个参数分别resolve
和 reject
。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。
resolve函数的作用是: 将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 fulfilled),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
reject函数的作用是: 将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
Promise对象实例的方法,then 和 catch:
.then方法: 用于指定调用成功时的回调函数。
then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例),因此可以采用链式写法,即then方法后面再调用另一个then方法。
.catch方法: 用于指定发生错误时的回调函数。
五、跨域的问题
问题一:什么是JS的同源策略和跨域问题?
同源策略:
所谓同源策略,指的是浏览器对不同源的脚本或者文本的访问方式进行的限制。比如源a的js不能读取或设置引入的源b的元素属性。
同源指两个页面具有相同的协议,主机(也常说域名),端口,三个要素缺一不可。
URL1 | URL2 | 说明 | 是否允许通信 |
---|---|---|---|
http://www.foo.com/js/a.js | http://www.foo.com/js/b.js | 协议、域名、端口都相同 | 允许 |
http://www.foo.com/js/a.js | http://www.foo.com:8888/js/b.js | 协议、域名相同,端口不同 | 不允许 |
https://www.foo.com/js/a.js | http://www.foo.com/js/b.js | 主机、域名相同,协议不同 | 不允许 |
http://www.foo.com/js/a.js | http://www.bar.com/js/b.js | 协议、端口相同,域名不同 | 不允许 |
http://www.foo.com/js/a.js | http://foo.com/js/b.js | 协议、端口相同,主域名相同,子域名不同 | 不允许 |
同源策略限制的不同源之间的交互主要针对的是 js中的XMLHttpRequest等请求,下面这些情况是完全不受同源策略限制的。
1、页面中的链接,重定向以及表单提交是不会受到同源策略限制的。
2、跨域资源嵌入是允许的,当然,浏览器限制了Javascript不能读写加载的内容。
即我们需要向不同源的 后台接口 发送 http请求去请求数据。
vue-cli开发环境开发的时候一定会涉及到跨域问题
因为vue-cli开发环境启动本地一个 localhost:端口号 node服务器,此时去请求数据接口一定是跨域的。
问题二:如何解决跨域问题?
1、通过 jquery 的 jsonp 形式解决跨域问题(小学生回答模式)
$.ajax({
url:'...../data.js',//可以不是本地域名
type:'get',
dataType:'jsonp', //jsonp格式访问
jsonpCallback:'aa' //获取数据的函数
})
2、在vue-cli项目中的 config 文件夹下的 index.js 配置文件中,配置 dev对象的 proxyTable对象,可通过node.js的代理服务器来实现跨域请求。
module.exports = {
publicPath: '/',
outputDir: 'dist',
assetsDir: 'static',
configureWebpack: {
devtool:'eval-source-map'
},
devServer: {
port: 8080,
open: true,
overlay: {
warnings: false,
errors: true
},
proxy: {
'/api': {
target: 'http://api/',
secure: false,
changeOrigin: true,
pathRewrite: {
'/api': '/api'
}
}
}
},
};
3、在服务器响应客户端的时候,带上 Access-Control-Allow-Origin:* 头信息 [推荐使用]
public class testFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) resp;
response.setHeader("Access-Control-Allow-Origin", "*"); //解决跨域访问报错
response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600"); //设置过期时间
response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, client_id, uuid, Authorization");
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // 支持HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // 支持HTTP 1.0. response.setHeader("Expires", "0");
chain.doFilter(req, res);
}
4、通过负载均衡服务工具(nginx)进行url转发
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
proxy_pass http://web1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
index index.html index.jsp login.jsp index.htm;
#root html;
#index index.html index.htm;
}
location /admin {
proxy_pass http://web2;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
index index.html index.jsp login.jsp index.htm;
}
...
}
来源:oschina
链接:https://my.oschina.net/liuxinzhou/blog/3194932