以前前端提到网络请求通常是指浏览器,现在随着Node.js和小程序的出现,网络请求不再受限到浏览器。本文将带您了解不同请求的原理,以及如何为您的项目选择合适的请求库。一、请求原理1.1浏览器浏览器通过XMLHttpRequest对象实现http请求。古时候ie6是借助ActiveXObject对象实现http请求的,现在已经没人用了,也不考虑兼容性。W3C标准新提出的FecthAPI是基于Promise实现的,调用起来比XMLHttpRequest对象更方便,但是老浏览器不支持Promise,需要对Promise进行pollyfilled。XMLHttpRequestletxhr=newXMLHttpRequest();xhr.open('get',url,true);xhr.send();xhr.onreadystatechange=function(){if(xhr.readyState===4&&xhr.status===200){让响应=JSON.parse(xhr.responseText);}}Fetchfetch(url).then(response=>response.json()).then(data=>console.log(data)).catch(e=>console.log("error",e))1.2节点.jsNode.js发布于2009年,是一个基于ChromeV8引擎的JavaScript运行环境。Node.js的顶层对象是全局的,没有window对象。不能通过XMLHttpRequest对象实现HTTP请求。Node.js通过引入http/https/http2模块来实现http请求。下面是一个http模块实现的例子:consthttp=require('http');constserver=http.createServer((req,res)=>{res.end('helloworld');});server.on('clientError',(err,socket)=>{socket.end('HTTP/1.1400BadRequest\r\n\r\n');});server.listen(8000);1.3ReactNativeReactNative是Facebook2015年开源的跨平台移动应用开发工具。ReactNative内置了XMLHttpRequestAPI,同时也提供了符合Web标准的FetchAPI,所以大部分可以在Web上使用的网络请求库也可以在ReactNative中使用。1.4WeexWeex是阿里2016年开源的跨平台移动应用开发工具。Weex通过封装模块调用原生函数,并提供流模块实现网络请求。1.5小程序2017年微信小程序上线,随后各大平台纷纷推出自己的小程序。由于小程序需要对http请求进行参数校验,兼容各种平台(iOS、Android)或版本问题,所以提供了自己的一套API,不提供window对象。下面以微信小程序和支付宝小程序官网为例:,y:''},header:{'content-type':'application/json'//默认值},success(res){console.log(res.data)}})支付宝小程序my.httpRequest({url:'http://httpbin.org/post',method:'POST',data:{from:'Alipay',production:'AlipayJSAPI',},dataType:'json',success:function(res){my.alert({content:'success'});},fail:function(res){my.alert({content:'fail'});},complete:function(res){my.hideLoading();my.alert({content:'complete'});}});2、请求库从上面可以看出,平台之间的请求方式存在各种差异,请求库就是为了解决这个差异。以下是目前流行的请求库。2.1$.ajax(浏览器支持)$.ajax是jQuery对XMLHttpRequest对象的兼容包。需要补充的是,ReactNative可以使用一些浏览器网络请求库,但是不能使用jQuery,因为jQuery也使用了很多只有浏览器才有而ReactNative没有的东西。另外,在现在使用框架的项目中,我们一般都是使用其他的请求库,或者根据项目封装XMLHttpRequest或者Fetch,对于网络请求不会引入jQuery。2.2Request(支持Node.js)Request是一个http库,封装了Node.js的http/https模块。varrequest=require('请求');request('http://www.google.com',function(error,response,body){console.log('error:',error);//如果发生错误则打印错误console.log('statusCode:',response&&response.statusCode);//如果收到响应则打印响应状态代码console.log('body:',body);//打印Google主页的HTML。});2.3SuperAgent(支持Node.js)SuperAgent类似于Request,是一个封装了Node.js的http/https模块的http库。varrequest=require('superagent')request.post('/api/pet').send({name:'Manny',species:'cat'}).set('X-API-Key','foobar').set('Accept','application/json').then(res=>{alert('yaygot'+JSON.stringify(res.body));});2.4Axios(支持ReactNative、Node、浏览器)Axios是一个基于promise的HTTP请求库,可以在浏览器和Node.js中使用。在浏览器中使用XMLHttpRequest,在Node.js中使用http/https模块。以下是一个示例请求:axios.get('/user?ID=12345').then(function(response){console.log(response);}).catch(function(error){console.log(error);});Vue2.0推荐使用Axios作为Vue的请求库。而在SSR中,我们既需要服务端请求,也需要客户端请求,所以通常会选择axios。2.5Fly.js(支持Node.js、微信小程序、Weex、ReactNative、快应用和浏览器)Fly.js是一个基于promise的HTTP请求库,可以在Node.js、微信小程序、Weex、ReactNative中使用、快应用和浏览器兼容以上平台。fly.get('/user?id=133').then(function(response){console.log(response);}).catch(function(error){console.log(error);});除了Fly.js,一些小程序开发框架本身就提供了与平台兼容的网络请求库,比如Taro.request。3.综上所述,不同请求库之间在API和用法上存在差异。在项目初期,根据兼容平台选择合适的请求库,会大大减少日后代码重构的麻烦。
