实际工作中各框架的 ajax 初始化 及 二次封装

在目前前后端分离的工作模式下,前端需要对接许多接口服务,对接的同时我们会发现很多时候会对请求做一些相同的处理,例如 阻止重复提交、根据服务的返回给前台一些相同的提示信息 或者 打印请求日志 等等。针对这种情况,我们可以通过简单的二次封装 http 请求方法,来简化我们的工作 并提高用户体验。
下面分别列举了 卡萨帝商城、海贝商城管理后台 和 数据中心 三个不同框架中对于 http 请求的实际应用,每个项目中封装的侧重点不同,但是不同框架处理问题的思路是基本一致的。
jQuery
需求: 部分服务需要校验用户登录,如未登录则应中止请求,跳转登陆页或给出提示
解决方法:设置拦截器
jQuery.ajaxSetup({ type : "post" , dataType : "json" , cache : false , box_obj : null , scroll : null , beforeSend : function (request) { // 创建一个拦截器,在请求发送出去之前做一次处理 // 判断用户是否登录,未登录则中止请求 并跳转登陆页或给出提示 if ( this .login && !istrsidssdssotoken()) { request.abort(); } }, success : function (data) { // 请求成功返回后可做统一处理,例如统一的弹层提示等 if (data.isSuccess) { } // 执行每个请求的 success_cb 方法,并传递请求的返回结果 if ( this .success_cb) { this .success_cb(data); } }, error : function (jqXHR, textStatus, errorThrown) { }});
$.ajax({ url : url, data : params, login : true , // 如果设置 login 为 true 则在请求前做登录校验 success_cb: function (data) { // 当前请求的成功回调 if (data.isSuccess) {}}});
AngularJS
需求:阻止重复提交,根据后台返回做某些统一处理
解决方法:记录每次发送的请求发送前校验,同一  url  请求是否在进行中 以及 请求参数是否一致
app.factory( 'trsGetData' , function ($http, $q, ngDialog, $state, $rootScope, $timeout, $httpParamSerializerJQLike,siteInfo) { $rootScope.repeatedlyClick = {}; //阻止重复提交 return function (url, params, funName, method) { if (!funName) { funName = "temporary" ; } // 如果是下载,则走单独逻辑 if (method == "download" ) { url = url + '?' ; for ( var param in params) { if (params[param]) { url += param + '=' + params[param] + '&' ; } } url = url.slice(0, -1); window.location.href = url; return false ; } if (method != "get" ) { method = "post" ; } var defer = $q.defer(); /** * 阻止重复提交 校验方法名和请求参数 */ if (!$rootScope.repeatedlyClick[funName] || $rootScope.repeatedlyClick[funName] !== JSON.stringify(params)) { $rootScope.repeatedlyClick[funName] = JSON.stringify(params); //记录方法funName提交的参数parms如果提交的参数相同则不会再次提交 $http({ method : method, url : url, headers : { 'formdata' : "1" , //用于wcm解析data 'Content-Type' : 'application/x-www-form-urlencoded;charset=UTF-8' , 'siteId' :siteInfo.curSite.siteId }, data : method == 'get' ? "" : $httpParamSerializerJQLike(params), params : method == 'get' ? params : "" , timeout : 60000 //超时时间30s }).success( function (data, status, headers, config) { $rootScope.repeatedlyClick[funName] = false ; /** * wcm登陆失败则跳转登陆页 * open服务 wcm未登录,请登录后再操作 * here应用 access-denied * wcm服务 boolean */ if ((data.resultMsg === "wcm未登录,请登录后再操作" || data.resultMsg === "access-denied" || headers( "TRSNotLogin" ))) { $rootScope.$emit( "userIntercepted" , "notLogin" , data); } if (!data.isSuccess || data.isSuccess == 'false' ) { if (data.resultMsg) { console.warn(data.resultMsg); } } defer.resolve(data); }).error( function (data, status, headers, config) { $rootScope.repeatedlyClick[funName] = false ; /** * 请求失败 则给出提示 */ if (status == -1 || status == 408) { } ngDialog.open({ template : 'common/404/dialog404.html' , className : 'ngdialog-theme-default' , width : 572, showClose : false , closeByDocument : false , closeByEscape : false , controller : [ '$scope' , function ($scope, $state) { $scope.dialog = { "dialogTitle" : "提示" , "dialogMessage" : "" , "dialogIcon" : "icon-cuowu" , "dialogConfirm" : "确定" , // "dialogCancel": "取消", "goHome" : function () { ngDialog.close(); }, "goBack" : function () { history.go(-1); ngDialog.close(); } }; }] }); defer.reject(data); }); } return defer.promise; }; });
trsGetData(envUrl + '/eshop/eshopcenter.do' , params, "isSiteHaveRight" , "post" );
Vue.js
需求:由于列表服务返回很慢,用户如果切换不同检索条件检索的话,有可能出现后请求的数据先返回,先请求的数据后返回的情况,导致页面展示数据与用户检索条件不符的情况
解决方法:相同的请求发出前设置拦截器取消正在进行中的相同请求
var promiseArr = {}trsGetData: function () { let cancel // 创建 http 请求 const httpServer = axios.create({ responseType : 'json' , cancelToken : new axios.CancelToken( function (c) { cancel = c }) }) httpServer.interceptors.request.use( function (config) { if (promiseArr[config.url]) { promiseArr[config.url]( '操作取消' ) // 取消相同请求 promiseArr[config.url] = cancel } else { promiseArr[config.url] = cancel // 记录当前请求的 cancel 方法 } return config }, function (err) { // return Promise.reject (error) }) return httpServer }
gUtils.trsGetData().post(Vue.prototype.apiUrl + 'vipcenter/memberRights/query' , data) .then( function (data) { if (data.data.isSuccess) { return data.data.data } else { return [] } }).catch( function (err) { console.warn(err) return catchMessage(err) }) }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是使用 Promise 二次封装 AJAX 的示例代码: ```javascript function ajax(url, method, data) { return new Promise(function(resolve, reject) { var xhr = new XMLHttpRequest(); xhr.open(method, url, true); xhr.setRequestHeader('Content-Type', 'application/json;charset=utf-8'); xhr.onreadystatechange = function() { if (xhr.readyState == 4) { if (xhr.status == 200) { resolve(JSON.parse(xhr.responseText)); } else { reject(xhr.statusText); } } } xhr.onerror = function() { reject('网络异常,请稍后重试'); } xhr.send(JSON.stringify(data)); }); } ``` 使用示例: ```javascript ajax('/api/user', 'POST', {name: 'test', age: 18}).then(function(res) { console.log(res); }).catch(function(error) { console.log('请求失败:' + error); }); ``` 在这个示例,我们定义了一个 `ajax` 函数,它接收三个参数:请求的 URL、请求的方法和请求的数据。它返回一个 Promise 对象,通过 `resolve` 和 `reject` 方法来处理请求成功和失败的情况。 在函数内部,我们创建了一个 XMLHttpRequest 对象,并设置请求的方法、请求头和请求数据。我们使用 `onreadystatechange` 事件来监听请求的状态变化,当请求状态为 4 时(即请求完成),我们判断状态码,如果为 200 则调用 `resolve` 方法,并将响应的 JSON 数据作为参数传递给它;否则调用 `reject` 方法,并将状态文本作为参数传递给它。在请求过程如果发生错误,则调用 `onerror` 事件处理函数,并将错误信息作为参数传递给 `reject` 方法。 在使用示例,我们调用 `ajax` 函数,并传递请求的 URL、请求方法和请求数据,然后使用 `then` 方法来处理请求成功的情况,使用 `catch` 方法来处理请求失败的情况。在成功的情况下,我们打印响应数据,在失败的情况下,我们打印错误信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值