ajax请求后台报没有body_前端常见面试 - 请求篇
对于前端来说,请求是前端日常工作必备的,通过请求才能与后端进行数据交互,尤其在现在前后端分离的开发模式下,请求显得就更加重要。因此,对于前端开发者来说,掌握请求就很重要。下面将从 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_前端常见面试 - 请求篇相关推荐
- ajax jq 图片上传请求头_全面分析前端的网络请求方式:Ajax ,jQuery ,axios,fetch
链接:https://juejin.im/post/5c9ac607f265da6103588b31 一.前端进行网络请求的关注点 大多数情况下,在前端发起一个网络请求我们只需关注下面几点: 传入基本 ...
- ajax获取java后台数据_jQuery ajax获取后台数据怎么在前端显示。
前后端分离以后,前端界面采用ajax与后台数据交互.现在从后台获取到下载文件的集合,怎么在前端一行一行显示,点击某一行可以直接跳转过去下载对应的文件. pageEncoding="UTF-8 ...
- 前端请求后台报错400
报错原因:前端请求的字段名称或者字段类型和后台编写的实体类不一样,或者前端提交的参数和后台需要的参数个数不匹配,导致无法封装,报错400. 解决方法:仔细对照前后端字段类型,保证字段类型一致
- 【JavaScript问题】JavaScript 请求后台报错 Invalid character found in the request target
文章目录 问题描述 问题分析 解决方法 微信公众号 问题描述 开发中,遇到这么一个问题,前端使用get方式请求SpringMVC的后台控制层方法,但是直接没有进方法断点,就报错了 java.lang. ...
- ajax怎么解决报414,如何解决HTTP 414“请求URI太长”错误?
根据约翰的回答,我将GET请求更改为POST请求.它可以工作,而无需更改服务器配置.所以我去寻找如何实现这一点.以下页面是有帮助的: 带有PHP的jQuery Ajax POST示例 (注意清理发布的 ...
- 前端常见面试基础问题
一.自我介绍 1.1 姓名.毕业院校(可说可不说).项目经历.年龄和工作年限少谈 二.vue相关 2.1 路由模式:哈希模式和history模式的区别 1.路径表现的外观上: 在vue的路由配置中有m ...
- img src请求后台值值能判断_图片src拼接后台返回ID
本文地址:http://www.cnblogs.com/veinyin/p/8507403.html 在学习 CSS 时只了解了给固定地址,但是如果给的是一个需要拼接的地址就蒙了,以下是基于 Vue ...
- 计算机网络常见面试问题 —— HTTP状态码以及常见的请求字段
HTTP状态码以及常见的请求字段 HTTP状态码以及常见的请求字段 1.HTTP 概述和特征 1.HTTP状态码 2.HTTP常见的请求字段 参考 HTTP状态码以及常见的请求字段 1.HTTP 概述 ...
- (一)导学(前端框架面试-聚焦Vue/React/Webpack)
导学 全面 高效 学习前提 前端常见面试流程 知识点介绍 Vue框架部分 React框架部分 工具部分 项目设计 讲解方式 注意事项 全面 全面的知识体系 大量的面试真题 完整的技术面试流程 高效 直 ...
最新文章
- STL与泛型编程(1)---模板
- JavaScript 闭包的详细分享(三种创建方式)(附小实例)
- iOS 不要用文本编辑pod file
- powershell 下独立silent 安装 浏览器问题
- 阿里巴巴Java开发规约插件p3c
- 1.13 编程基础之综合应用 05 素数回文数的个数 python
- 别急,MIUI 11还有惊喜!下一代MIUI项目已开拔
- linux上python3的安装
- 编程修养 阅读笔记三
- 商城口碑高的蓝牙耳机好用吗?十大高人气蓝牙耳机测评推荐
- 项目总结报告(联东U谷)
- Pycharm 远程连接服务器(ssh)运行深度学习代码 | 详细步骤
- STM32CubeMx + HighSpeed USB + FreeRTOS
- E.03.08. Scrapped Plans for London Concert Hall Sour Mood for U.K. Musicians
- C语言阶梯程序,阶梯式C语言程序设计实验指导书.pdf
- 2021年全球与中国水上巡航行业市场规模及发展前景分析
- Git Alias(git快捷命令别名设置)
- 5 RRC Measurement -- GAP
- ShareSDK微信分享时的坑
- 软件中广告插件删除方法
热门文章
- (Prototype)原型模式的Java实现(转)
- extjs combobox分页查询
- sap 無法建立 activex 元件_安徽陶瓷膜芯元件
- php识别号码格式豹子,[转载]php新手入门之PHP常用特殊运算符号
- python graphql query返回一组字典数据_Python的sqlalchemy使用原生sql查询如何返回字典形式的数组?...
- nio java 内核拷贝_大文件拷贝,试试NIO的内存映射
- 拖链电缆 机器人电缆_trvv高柔性拖链电缆
- oracle 存储 更新,oracle 更新空间数据存储过程语句
- 我的世界java版怎么装在u盘_我的世界选择器参数怎么使用?
- 获取oracle 表字段描述,几种获取oracle用户表字段信息的方法