前端http请求和常见的几个请求技术做具体的讲解

更新日期: 2020-02-26阅读: 2.4k标签: 请求

对于前端来说,请求是前端日常工作必备的,通过请求才能与后端进行数据交互,尤其在现在前后端分离的开发模式下,请求显得就更加重要。因此,对于前端开发者来说,掌握请求就很重要。下面将从http请求和常见的几个请求技术做具体的讲解


一、XMLHttpRequest

        XMLHttpRequest一开始只是微软浏览器提供的一个接口,后来各大浏览器纷纷效仿也提供了这个接口,再后来W3C对它进行了标准化,按照标准前后可以分为两个版本,具体阐述如下:

版本以(老版本):
//新建一个XMLHttpRequest对象
var xhr=new XMLHttpRequest();

//进行请求
xhr.open('GET', 'url');
xhr.send();

//等待服务器响应
xhr.onreadystatechange = function(){
    //该函数会被调用四次,因此需要判断状态是否为4
    if ( xhr.readyState == 4 && xhr.status == 200 ) {
      alert( xhr.responseText );

    } else {

      alert( xhr.statusText );

    }
};

        在老版本中的,对应的具体属性说明如下:

  1. xhr.readyState:XMLHttpRequest对象的状态,等于4表示数据已经接收完毕。
  2. xhr.status:服务器返回的状态码,等于200表示一切正常。
  3. xhr.responseText:服务器返回的文本数据
  4. xhr.responseXML:服务器返回的XML格式的数据
  5. xhr.statusText:服务器返回的状态文本。

        老版本因为不是统一的标准,各个浏览器厂商在实现的时候都有一定的差异,而且在存在一些缺陷:

  1. 只支持文本数据的传送,无法用来读取和上传二进制文件。
  2. 传送和接收数据时,没有进度信息,只能提示有没有完成。
  3. 受到"同域限制"(Same Origin Policy),只能向同一域名的服务器请求数据。
版本二(标准后的版本):

        为了更好的使用XMLHttpRequest,w3school发布了标准版本,该版本弥补了版本一的缺陷,也被各大浏览器厂商接受并实现。具体为:

  1. 可以设置HTTP请求的时限。
  2. 可以使用FormData对象管理表单数据。
  3. 可以上传文件。
  4. 可以请求不同域名下的数据(跨域请求)。
  5. 可以获取服务器端的二进制数据。
  6. 可以获得数据传输的进度信息。

当然,一般为了友好的进行兼容各个浏览器,会采用对浏览器进行判断并进行兼容性模式来获取XMLHttpRequest的对象

var xhr;
if (window.XMLHttpRequest) { // Mozilla, Safari...
  xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
 try {
    xhr = new ActiveXObject('Msxml2.XMLHTTP');
 } catch (e) {
 try {
      xhr = new ActiveXObject('Microsoft.XMLHTTP'); //IE5,6
 } catch (e) {}
 }
}
// 请求成功回调函数
xhr.onload = e => {
    console.log('request success');
};
// 请求结束
xhr.onloadend = e => {
    console.log('request loadend');
};
// 请求出错
xhr.onerror = e => {
    console.log('request error');
};
// 请求超时
xhr.ontimeout = e => {
    console.log('request timeout');
};
// 请求回调函数.XMLHttpRequest标准又分为Level 1和Level 2,这是Level 1和的回调处理方式
// xhr.onreadystatechange = () => {
//  if (xhr.readyState !== 4) {
//  return;
//  }
//  const status = xhr.status;
//  if ((status >= 200 && status < 300) || status === 304) {
//  console.log('request success');
//  } else {
//  console.log('request error');
//  }
//  };

xhr.timeout = 0; // 设置超时时间,0表示永不超时
// 初始化请求
xhr.open('GET/POST/DELETE/...', '/url', true || false);
// 设置期望的返回数据类型 'json' 'text' 'document' ...
xhr.responseType = '';
// 设置请求头
xhr.setRequestHeader('', '');
// 发送请求
xhr.send(null || new FormData || 'a=1&b=2' || 'json字符串');


二、ajax请求

        AJAX 是一种与服务器交换数据的技术,可以在不重新载入整个页面的情况下更新网页的一部分,其实就是对XMLHttpRequest的封装,可以直接引入jquery工具包来进行调用ajax请求(jquery是一个js工具包,其特点是:写得少,做得多),具体的ajax常用方式如下:

方法描述
$.ajax()执行异步 AJAX 请求
$.ajaxPrefilter()在每个请求发送之前且被 $.ajax() 处理之前,处理自定义 Ajax 选项或修改已存在选项
$.ajaxSetup()为将来的 AJAX 请求设置默认值
$.ajaxTransport()创建处理 Ajax 数据实际传送的对象
$.get()使用 AJAX 的 HTTP GET 请求从服务器加载数据
$.getJSON()使用 HTTP GET 请求从服务器加载 JSON 编码的数据
$.getScript()使用 AJAX 的 HTTP GET 请求从服务器加载并执行 JavaScript
$.param()创建数组或对象的序列化表示形式(可用于 AJAX 请求的 URL 查询字符串)
$.post()使用 AJAX 的 HTTP POST 请求从服务器加载数据
ajaxComplete()规定 AJAX 请求完成时运行的函数
ajaxError()规定 AJAX 请求失败时运行的函数
ajaxSend()规定 AJAX 请求发送之前运行的函数
ajaxStart()规定第一个 AJAX 请求开始时运行的函数
ajaxStop()规定所有的 AJAX 请求完成时运行的函数
ajaxSuccess()规定 AJAX 请求成功完成时运行的函数
load()从服务器加载数据,并把返回的数据放置到指定的元素中
serialize()编码表单元素集为字符串以便提交
serializeArray()编码表单元素集为 names 和 values 的数组
优点:
  • 对原生XHR的封装
  • 针对MVC的编程
  • 完美的兼容性
  • 支持jsonp
缺点:
  • 不符合MVVM
  • 异步模型不够现代,不支持链式,代码可读性差
  • 整个Jquery太大,引入成本过高

        当然,我们可以直接使用XMLHttpReqeust来进行实现自己的ajax封装,具体代码如下:

const http = {
  /**
   * js封装ajax请求
   * >>使用new XMLHttpRequest 创建请求对象,所以不考虑低端IE浏览器(IE6及以下不支持XMLHttpRequest)
   * >>使用es6语法,如果需要在正式环境使用,则可以用babel转换为es5语法 https://babeljs.cn/docs/setup/#installation
   *  @param settings 请求参数模仿jQuery ajax
   *  调用该方法,data参数需要和请求头Content-Type对应
   *  Content-Type                        data                                     描述
   *  application/x-www-form-urlencoded   'name=哈哈&age=12'或{name:'哈哈',age:12}  查询字符串,用&分割
   *  application/json                     name=哈哈&age=12'                        json字符串
   *  multipart/form-data                  new FormData()                           FormData对象,当为FormData类型,不要手动设置Content-Type
   *  注意:请求参数如果包含日期类型.是否能请求成功需要后台接口配合
   */
  ajax: (settings = {}) => {
    // 初始化请求参数
    let _s = Object.assign({
      url: '', // string
      type: 'GET', // string 'GET' 'POST' 'DELETE'
      dataType: 'json', // string 期望的返回数据类型:'json' 'text' 'document' ...
      async: true, //  boolean true:异步请求 false:同步请求 required
      data: null, // any 请求参数,data需要和请求头Content-Type对应
      headers: {}, // object 请求头
      timeout: 1000, // string 超时时间:0表示不设置超时
      beforeSend: (xhr) => {
      },
      success: (result, status, xhr) => {
      },
      error: (xhr, status, error) => {
      },
      complete: (xhr, status) => {
      }
    }, settings);
    // 参数验证
    if (!_s.url || !_s.type || !_s.dataType || !_s.async) {
      alert('参数有误');
      return;
    }
    // 创建XMLHttpRequest请求对象
    let xhr = new XMLHttpRequest();
    // 请求开始回调函数
    xhr.addEventListener('loadstart', e => {
      _s.beforeSend(xhr);
    });
    // 请求成功回调函数
    xhr.addEventListener('load', e => {
      const status = xhr.status;
      if ((status >= 200 && status < 300) || status === 304) {
        let result;
        if (xhr.responseType === 'text') {
          result = xhr.responseText;
        } else if (xhr.responseType === 'document') {
          result = xhr.responseXML;
        } else {
          result = xhr.response;
        }
        // 注意:状态码200表示请求发送/接受成功,不表示业务处理成功
        _s.success(result, status, xhr);
      } else {
        _s.error(xhr, status, e);
      }
    });
    // 请求结束
    xhr.addEventListener('loadend', e => {
      _s.complete(xhr, xhr.status);
    });
    // 请求出错
    xhr.addEventListener('error', e => {
      _s.error(xhr, xhr.status, e);
    });
    // 请求超时
    xhr.addEventListener('timeout', e => {
      _s.error(xhr, 408, e);
    });
    let useUrlParam = false;
    let sType = _s.type.toUpperCase();
    // 如果是"简单"请求,则把data参数组装在url上
    if (sType === 'GET' || sType === 'DELETE') {
      useUrlParam = true;
      _s.url += http.getUrlParam(_s.url, _s.data);
    }
    // 初始化请求
    xhr.open(_s.type, _s.url, _s.async);
    // 设置期望的返回数据类型
    xhr.responseType = _s.dataType;
    // 设置请求头
    for (const key of Object.keys(_s.headers)) {
      xhr.setRequestHeader(key, _s.headers[key]);
    }
    // 设置超时时间
    if (_s.async && _s.timeout) {
      xhr.timeout = _s.timeout;
    }
    // 发送请求.如果是简单请求,请求参数应为null.否则,请求参数类型需要和请求头Content-Type对应
    xhr.send(useUrlParam ? null : http.getQueryData(_s.data));
  },
  // 把参数data转为url查询参数
  getUrlParam: (url, data) => {
    if (!data) {
      return '';
    }
    let paramsStr = data instanceof Object ? http.getQueryString(data) : data;
    return (url.indexOf('?') !== -1) ? paramsStr : '?' + paramsStr;
  },
  // 获取ajax请求参数
  getQueryData: (data) => {
    if (!data) {
      return null;
    }
    if (typeof data === 'string') {
      return data;
    }
    if (data instanceof FormData) {
      return data;
    }
    return http.getQueryString(data);
  },
  // 把对象转为查询字符串
  getQueryString: (data) => {
    let paramsArr = [];
    if (data instanceof Object) {
      Object.keys(data).forEach(key => {
        let val = data[key];
        // todo 参数Date类型需要根据后台api酌情处理
        if (val instanceof Date) {
          // val = dateFormat(val, 'yyyy-MM-dd hh:mm:ss');
        }
        paramsArr.push(encodeURIComponent(key) + '=' + encodeURIComponent(val));
      });
    }
    return paramsArr.join('&');
  }
}


三、vue-resource请求

        vue-resource是Vue.js的一款插件,它可以通过XMLHttpRequest或JSONP发起请求并处理响应。也就是说,$.ajax能做的事情,vue-resource插件一样也能做到,而且vue-resource的API更为简洁。另外,vue-resource还提供了非常有用的inteceptor功能,使用inteceptor可以在请求前和请求后附加一些行为,比如使用inteceptor在ajax请求时显示loading界面。

特点
  1. 体积小
    vue-resource非常小巧,在压缩以后只有大约12KB,服务端启用gzip压缩后只有4.5KB大小,这远比jQuery的体积要小得多。
  2. 支持主流的浏览器
    和Vue.js一样,vue-resource除了不支持IE 9以下的浏览器,其他主流的浏览器都支持。
  3. 支持Promise API和URI Templates
    Promise是ES6的特性,Promise的中文含义为“先知”,Promise对象用于异步计算。
    URI Templates表示URI模板,有些类似于ASP.NET MVC的路由模板。
  4. 支持拦截器
    拦截器是全局的,拦截器可以在请求发送前和发送请求后做一些处理。
    拦截器在一些场景下会非常有用,比如请求发送前在headers中设置access_token,或者在请求失败时,提供共通的处理方式。
常用api
  1. get(url, [options])
  2. head(url, [options])
  3. delete(url, [options])
  4. jsonp(url, [options])
  5. post(url, [body], [options])
  6. put(url, [body], [options])
  7. patch(url, [body], [options])
客户端请求方法服务端处理方法
this.$http.get(...)Getxxx
this.$http.post(...)Postxxx
this.$http.put(...)Putxxx
this.$http.delete(...)Deletexxx
option详解
参数类型描述
urlstring请求的URL
methodstring请求的HTTP方法,例如:'GET', 'POST'或其他HTTP方法
bodyObject, FormData stringrequest body
paramsObject请求的URL参数对象
headersObjectrequest header
timeoutnumber单位为毫秒的请求超时时间 (0 表示无超时时间)
beforefunction(request)请求发送前的处理函数,类似于jQuery的beforeSend函数
progressfunction(event)ProgressEvent回调处理函数
credentialsboolean表示跨域请求时是否需要使用凭证
emulateHTTPboolean发送PUT, PATCH, DELETE请求时以HTTP POST的方式发送,并设置请求头的X-HTTP-Method-Override
emulateJSONboolean将request body以application/x-www-form-urlencoded content type发送

四、fetch

  1. fetch是基于promise实现的,也可以结合async/await
  2. fetch请求默认是不带cookie的,需要设置fetch(URL,{credentials:’include’})。 
  3. Credentials有三种参数:same-origin,include,*
  4. 服务器返回400 500 状态码时并不会reject,只有网络出错导致请求不能完成时,fetch才会被reject
  5. 所有版本的 IE 均不支持原生 Fetch
  6. fetch是widow的一个方法
fetch(url).then(function(response) {
 return response.json();
}).then(function(data) {
  console.log(data);
}).catch(function(e) {
  console.log("Oops, error");
});

        可配合es6的箭头函数进行使用

fetch(url).then(response => response.json())
 .then(data => console.log(data))
 .catch(e => console.log("Oops, error", e))


五、axios

        Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中

特点
  • 从浏览器中创建XMLHttpRequests
  • 从 node.js 创建http请求
  • 支持PromiseAPI
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换 JSON 数据
  • 客户端支持防御XSRF
常用api
  1. axios.request(config)
  2. axios.get(url[, config])
  3. axios.delete(url[, config])
  4. axios.head(url[, config])
  5. axios.options(url[, config])
  6. axios.post(url[, data[, config]])
  7. axios.put(url[, data[, config]])
  8. axios.patch(url[, data[, config]]
实例

get请求

// 为给定 ID 的 user 创建请求
axios.get('/user?ID=12345')
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

// 可选地,上面的请求可以这样做
axios.get('/user', {
    params: {
      ID: 12345
    }
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

post请求

axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

并发请求

function getUserAccount() {
  return axios.get('/user/12345');
}

function getUserPermissions() {
  return axios.get('/user/12345/permissions');
}

axios.all([getUserAccount(), getUserPermissions()])
  .then(axios.spread(function (acct, perms) {
    // 两个请求现在都执行完成
  }));

拦截器

// 添加请求拦截器
axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  });

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
    // 对响应数据做点什么
    return response;
  }, function (error) {
    // 对响应错误做点什么
    return Promise.reject(error);
  });

取消请求

var CancelToken = axios.CancelToken;
var source = CancelToken.source();

axios.get('/user/12345', {
  cancelToken: source.token
}).catch(function(thrown) {
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
    // 处理错误
  }
});

// 取消请求(message 参数是可选的)
source.cancel('Operation canceled by the user.');


链接: https://fly63.com/article/detial/8413

nginx 301跳转https后post请求失效问题解决

强制把http请求跳转到https,结果发现App有部分的功能不能使用,因为App一共设置了4种请求方式,分别是GET,POST,DELETE和OPTIONS方式,设置301跳转后所有的请求方法都变成了GET方式,导致一些功能无法正常使用.

HTTP请求的11个处理阶段

几乎所以有关Nginx书只要是讲深入点的就会讲到Nginx请求的11个处理阶段,要记住这些真是不易,人脑特别不擅长记住各种东西,只能做些索引罢了,能做到知道这个知识点在哪儿能找到不就行了,可是你去面试还是问这些理论,所以这里汇总下记录如下

http请求过程的7个步骤

HTTP通信机制是在一次完整的HTTP通信过程中,Web浏览器与Web服务器之间将完成下列7个步骤:建立TCP连接、Web浏览器向Web服务器发送请求命令、Web浏览器发送请求头信息、 Web服务器应答

http请求的几种类型

http请求中的8种请求方法:opions 返回服务器针对特定资源所支持的HTML请求方法 ,Get 向特定资源发出请求,Post 向指定资源提交数据进行处理请求

nodejs http请求相关总结

通过node提供的http模块,可以通过其提供的get()和request()两个方法发起http请求,get()是对request()方法的封装,方便发起get请求,如果要实现post请求,那么需要对request()方法进行封装。

ajax异步请求302分析

遇到这样一种情况,打开网页两个窗口a,b(都是已经登录授权的),在a页面中退出登录,然后在b页面执行增删改查,这个时候因为授权原因,b页面后端的请求肯定出现异常(对这个异常的处理,进行内部跳转处理),b页面中的ajax请求的回调中就会出现问题

POST 请求的三种常见数据提交格式

本文所讲的 POST 请求是 HTTP/1.1 协议中规定的众多 HTTP 请求方法的其中最常用的一个。一般使用 POST 请求方法向服务器发送数据(主要是一些创建更新操作),本文讨论的是 POST 请求方法常用的四种数据提交格式。

flutter之网络请求dio封装,拦截器的封装

flutter一直很火的网络请求插件dio,直接上代码,写成一个类,可以直接使用,包含请求的封装,拦截器的封装

HTTP请求过程

当我们在web浏览器的地址栏中输入: www.baidu.com,然后回车,到底发生了什么?DNS域名解析采用的是递归查询的方式,过程是,先去找DNS缓存->缓存找不到就去找根域名服务器->根域名又会去找下一级

nginx是怎么处理http请求的?

nginx首先决定要用配置文件里的哪个server{}块来处理,假设有下面的server{}配置;nginx会根据过来的http请求头里的Host字段里的值,来判断使用哪个server{}。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!