fetch是一种HTTP数据请求的方式,是XMLHttpRequest的一种替代方案。fetch不是ajax的进一步封装,而是原生js。Fetch函数就是原生js,没有使用XMLHttpRequest对象。

ajax

  • 使用步骤
    1.创建XmlHttpRequest对象
    2.调用open方法设置基本请求信息
    3.设置发送的数据,发送请求
    4.注册监听的回调函数
    5.拿到返回值,对页面进行更新
  1. //1.创建Ajax对象
  2. if(window.XMLHttpRequest){
  3. var oAjax=new XMLHttpRequest();
  4. }else{
  5. var oAjax=new ActiveXObject("Microsoft.XMLHTTP");
  6. }
  7. //2.连接服务器(打开和服务器的连接)
  8. oAjax.open('GET', url, true);
  9. //3.发送
  10. oAjax.send();
  11. //4.接收
  12. oAjax.onreadystatechange=function (){
  13. if(oAjax.readyState==4){
  14. if(oAjax.status==200){
  15. //alert('成功了:'+oAjax.responseText);
  16. fnSucc(oAjax.responseText);
  17. }else{
  18. //alert('失败了');
  19. if(fnFaild){
  20. fnFaild();
  21. }
  22. }
  23. }
  24. };

fetch

  • 特点
    1、第一个参数是URL:
    2、第二个是可选参数,可以控制不同配置的 init 对象
    3、使用了 JavaScript Promises 来处理结果/回调:
  1. fetch(url).then(response => response.json())
  2. .then(data => console.log(data))
  3. .catch(e => console.log("Oops, error", e))
  • 更酷的一点
    你可以通过Request构造器函数创建一个新的请求对象,你还可以基于原有的对象创建一个新的对象。 新的请求和旧的并没有什么不同,但你可以通过稍微调整配置对象,将其用于不同的场景。例如:
  1. var req = new Request(URL, {method: 'GET', cache: 'reload'});
  2. fetch(req).then(function(response) {
  3. return response.json();
  4. }).then(function(json) {
  5. insertPhotos(json);
  6. });

上面的代码中我们指明了请求使用的方法为GET,并且指定不缓存响应的结果,你可以基于原有的GET请求创建一个POST请求,它们具有相同的请求源。代码如下:

  1. // 基于req对象创建新的postReq对象
  2. var postReq = new Request(req, {method: 'POST'});

fetch和ajax 的主要区别

1、fetch()返回的promise将不会拒绝http的错误状态,即使响应是一个HTTP 404或者500
2、在默认情况下 fetch不会接受或者发送cookies

fetch的配置

Promise fetch(String url [, Object options]);
Promise fetch(Request req [, Object options]);
更多配置

fetch封装

  1. export default async(url = '', data = {}, type = 'GET', method = 'fetch') => {
  2. type = type.toUpperCase();
  3. url = baseUrl + url;
  4. if (type == 'GET') {
  5. let dataStr = ''; //数据拼接字符串
  6. Object.keys(data).forEach(key => {
  7. dataStr += key + '=' + data[key] + '&';
  8. })
  9. if (dataStr !== '') {
  10. dataStr = dataStr.substr(0, dataStr.lastIndexOf('&'));
  11. url = url + '?' + dataStr;
  12. }
  13. }
  14. if (window.fetch && method == 'fetch') {
  15. let requestConfig = {
  16. credentials: 'include',//为了在当前域名内自动发送 cookie , 必须提供这个选项
  17. method: type,
  18. headers: {
  19. 'Accept': 'application/json',
  20. 'Content-Type': 'application/json'
  21. },
  22. mode: "cors",//请求的模式
  23. cache: "force-cache"
  24. }
  25. if (type == 'POST') {
  26. Object.defineProperty(requestConfig, 'body', {
  27. value: JSON.stringify(data)
  28. })
  29. }
  30. try {
  31. const response = await fetch(url, requestConfig);
  32. const responseJson = await response.json();
  33. return responseJson
  34. } catch (error) {
  35. throw new Error(error)
  36. }
  37. } else {
  38. return new Promise((resolve, reject) => {
  39. let requestObj;
  40. if (window.XMLHttpRequest) {
  41. requestObj = new XMLHttpRequest();
  42. } else {
  43. requestObj = new ActiveXObject;
  44. }
  45. let sendData = '';
  46. if (type == 'POST') {
  47. sendData = JSON.stringify(data);
  48. }
  49. requestObj.open(type, url, true);
  50. requestObj.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  51. requestObj.send(sendData);
  52. requestObj.onreadystatechange = () => {
  53. if (requestObj.readyState == 4) {
  54. if (requestObj.status == 200) {
  55. let obj = requestObj.response
  56. if (typeof obj !== 'object') {
  57. obj = JSON.parse(obj);
  58. }
  59. resolve(obj)
  60. } else {
  61. reject(requestObj)
  62. }
  63. }
  64. }
  65. })
  66. }
  67. }