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

1.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字符串');

2.ajax 请求

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

优点:
  • 对原生 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('&');  }}

3.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
  • get(url, [options])
  • head(url, [options])
  • delete(url, [options])
  • jsonp(url, [options])
  • post(url, [body], [options])
  • put(url, [body], [options])
  • patch(url, [body], [options])

option 详解

4.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))

5.axios

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

特点:
  • 从浏览器中创建 XMLHttpRequests
  • 从 node.js 创建 http 请求
  • 支持 PromiseAPI
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换 JSON 数据
  • 客户端支持防御 XSRF
常用 api:
  • axios.request(config)
  • axios.get(url[, config])
  • axios.delete(url[, config])
  • axios.head(url[, config])
  • axios.options(url[, config])
  • axios.post(url[, data[, config]])
  • axios.put(url[, data[, config]])
  • 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);  });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.');

当然,无论选择哪一种方式都需要自身结合业务的需要和自我的认知,没有哪个绝对的优秀,也没有哪个绝对不优秀。

ajax请求后台报没有body_前端常见面试 - 请求篇相关推荐

  1. ajax jq 图片上传请求头_全面分析前端的网络请求方式:Ajax ,jQuery ,axios,fetch

    链接:https://juejin.im/post/5c9ac607f265da6103588b31 一.前端进行网络请求的关注点 大多数情况下,在前端发起一个网络请求我们只需关注下面几点: 传入基本 ...

  2. ajax获取java后台数据_jQuery ajax获取后台数据怎么在前端显示。

    前后端分离以后,前端界面采用ajax与后台数据交互.现在从后台获取到下载文件的集合,怎么在前端一行一行显示,点击某一行可以直接跳转过去下载对应的文件. pageEncoding="UTF-8 ...

  3. 前端请求后台报错400

    报错原因:前端请求的字段名称或者字段类型和后台编写的实体类不一样,或者前端提交的参数和后台需要的参数个数不匹配,导致无法封装,报错400. 解决方法:仔细对照前后端字段类型,保证字段类型一致

  4. 【JavaScript问题】JavaScript 请求后台报错 Invalid character found in the request target

    文章目录 问题描述 问题分析 解决方法 微信公众号 问题描述 开发中,遇到这么一个问题,前端使用get方式请求SpringMVC的后台控制层方法,但是直接没有进方法断点,就报错了 java.lang. ...

  5. ajax怎么解决报414,如何解决HTTP 414“请求URI太长”错误?

    根据约翰的回答,我将GET请求更改为POST请求.它可以工作,而无需更改服务器配置.所以我去寻找如何实现这一点.以下页面是有帮助的: 带有PHP的jQuery Ajax POST示例 (注意清理发布的 ...

  6. 前端常见面试基础问题

    一.自我介绍 1.1 姓名.毕业院校(可说可不说).项目经历.年龄和工作年限少谈 二.vue相关 2.1 路由模式:哈希模式和history模式的区别 1.路径表现的外观上: 在vue的路由配置中有m ...

  7. img src请求后台值值能判断_图片src拼接后台返回ID

    本文地址:http://www.cnblogs.com/veinyin/p/8507403.html  在学习 CSS 时只了解了给固定地址,但是如果给的是一个需要拼接的地址就蒙了,以下是基于 Vue ...

  8. 计算机网络常见面试问题 —— HTTP状态码以及常见的请求字段

    HTTP状态码以及常见的请求字段 HTTP状态码以及常见的请求字段 1.HTTP 概述和特征 1.HTTP状态码 2.HTTP常见的请求字段 参考 HTTP状态码以及常见的请求字段 1.HTTP 概述 ...

  9. (一)导学(前端框架面试-聚焦Vue/React/Webpack)

    导学 全面 高效 学习前提 前端常见面试流程 知识点介绍 Vue框架部分 React框架部分 工具部分 项目设计 讲解方式 注意事项 全面 全面的知识体系 大量的面试真题 完整的技术面试流程 高效 直 ...

最新文章

  1. STL与泛型编程(1)---模板
  2. JavaScript 闭包的详细分享(三种创建方式)(附小实例)
  3. iOS 不要用文本编辑pod file
  4. powershell 下独立silent 安装 浏览器问题
  5. 阿里巴巴Java开发规约插件p3c
  6. 1.13 编程基础之综合应用 05 素数回文数的个数 python
  7. 别急,MIUI 11还有惊喜!下一代MIUI项目已开拔
  8. linux上python3的安装
  9. 编程修养 阅读笔记三
  10. 商城口碑高的蓝牙耳机好用吗?十大高人气蓝牙耳机测评推荐
  11. 项目总结报告(联东U谷)
  12. Pycharm 远程连接服务器(ssh)运行深度学习代码 | 详细步骤
  13. STM32CubeMx + HighSpeed USB + FreeRTOS
  14. E.03.08. Scrapped Plans for London Concert Hall Sour Mood for U.K. Musicians
  15. C语言阶梯程序,阶梯式C语言程序设计实验指导书.pdf
  16. 2021年全球与中国水上巡航行业市场规模及发展前景分析
  17. Git Alias(git快捷命令别名设置)
  18. 5 RRC Measurement -- GAP
  19. ShareSDK微信分享时的坑
  20. 软件中广告插件删除方法

热门文章

  1. (Prototype)原型模式的Java实现(转)
  2. extjs combobox分页查询
  3. sap 無法建立 activex 元件_安徽陶瓷膜芯元件
  4. php识别号码格式豹子,[转载]php新手入门之PHP常用特殊运算符号
  5. python graphql query返回一组字典数据_Python的sqlalchemy使用原生sql查询如何返回字典形式的数组?...
  6. nio java 内核拷贝_大文件拷贝,试试NIO的内存映射
  7. 拖链电缆 机器人电缆_trvv高柔性拖链电缆
  8. oracle 存储 更新,oracle 更新空间数据存储过程语句
  9. 我的世界java版怎么装在u盘_我的世界选择器参数怎么使用?
  10. 获取oracle 表字段描述,几种获取oracle用户表字段信息的方法