首先举例说明一下我这里需要取消Http请求这个需求的来源,在实际项目开发中,有一个指令my-list,这个指令负责请求数据,分页查询数据以及把数据渲染到dom中;第二个指令是my-sort指令,这个指令负责选择排序选项,选择排序选项之后通过修改请求参数,然后让my-list重新请求数据;第三个指令是my-filter,这个指令负责选择过滤的参数,这个参数可能是一个模糊查询的字段,可以能是一个日期,也可能是一个时间;就这样通过给指令分配职责,就可以实现按照任意字段实现排序过滤分页查询的功能,现在的问题是,三个指令的初始化时间顺序是不一定相同的。三个指令初始化完成之后,分别调用my-list的请求数据的函数,其中最后一个请求才是我们需要的,因为最后一个请求才是携带了我们需要的所有的参数,如果是my-sort先初始化并调用my-list请求数据,那么就会缺少过滤的参数,同理my-filter先初始化也一样,所以现在的目标是,多个请求同时执行,每一个请求都会把上一次请求取消,这样就会保留最后一个请求,这个才是正确的初始化的请求。
正文来了,angularJs如何取消请求:
var $q = {}; /*angularJs服务,在定义controller的时候可以在参数中自动注入,其他directive、Service类似*/ var $http = {}; /*angularJs服务,在定义controller的时候可以在参数中自动注入,其他directive、Service类似*/ var func = {}; /*回调方法,就是一个简单的函数*/ var param = {}; /*你执行请求需要传递的参数,如果是get请求,$http会自动把param对象解析到地址上*/ /*-------------------------------------------------------------------------------------------------------*/ /* * 执行单个请求的时候 */ var cancelRequest = $q.defer(); /*如果是get请求,格式应该是这样的,url地址+config对象两个参数,第二个参数就是config对象,config对象中包含你的请求参数*/ $http.get('/xxx', { params: param,/*你执行请求需要传递的参数*/ timeout: cancelRequest.promise /*当你需要手动取消请求的时候,需要给timeout传递一个promise对象*/ }) .success(func) /*请求成功回调*/ .error(func); /*请求失败回调*/ /*如果是post请求,格式就应该是三个参数,url地址+param请求参数+config对象*/ $http.post('/xxx', param,/*你执行请求需要传递的参数*/ {timeout: cancelRequest.promise}) /*config对象*/ .success(func) /*请求成功回调*/ .error(func); /*请求失败回调*/ /*如果你需要取消请求,则调用一下函数即可*/ cancelRequest.resolve(); /*-------------------------------------------------------------------------------------------------------*/ /* * 多个请求同时执行的时候,需要一个对象保存cancelRequest * 每次执行请求步骤: * 1、在执行请求之前判断对象中保存的cancelRequest是否存在,如果存在则调用 cancelRequest.resolve(); * 2、创建新的cancelRequest,请求保存到一个对象中 var cancelRequest = $q.defer(); * 3、判断请求类型,post、get,执行请求传入对应的参数 */ /*个人示例代码*/ function executeRequest(url,param,success,error,requestMethod,options) { options.isLoading && options.cancelRequest && (options.cancelRequest.resolve()); options.cancelRequest = $q.defer(); switch (options.requestMethod) { case 'get': $http[requestMethod](url,{ params: param, timeout: options.cancelRequest.promise } ).success(function (data) { success && success(data); }).error(function (data) { error && error(data); }); break; case 'post': $http[requestMethod]( url, param, {timeout: options.cancelRequest.promise} ).success(function (data) { success && success(data); }).error(function (data) { error && error(data); }); break; } } /*以java后台spring mvc应用为例*/ /*如果是get请求,不需要加任何注解,参数pojo类可以直接获取url地址参数,前提得是get请求*/
@RequestMapping("testRequestParam") public Map<String,Object> testRequestParam(HgWeekReport param) { Map<String,Object> result = new HashMap<>(); result.put("success",true); result.put("param",param); return result; }/* 如果是 post 请求,需要在获取参数的 pojo 类参数前面加上 @RequestBody 注解 */
@RequestMapping("testRequestBody") public Map<String,Object> testRequestBody(@RequestBody HgWeekReport param) { Map<String,param); return result; }/* 如果 pojo 类参数前加上 @modelattribute 注解,好像是无论是 get 请求还是 post 请求都可以获取到请求的参数信息 */
@RequestMapping("testModelAttribute") public Map<String,Object> testModelAttribute(@modelattribute HgWeekReport param) { Map<String,param); return result; }
/*这里从网上抄一些get请求和post请求的区别,出处:https://www.zhihu.com/question/28586791*/ /* 1、GET后退按钮/刷新无害,POST数据会被重新提交(浏览器应该告知用户数据会被重新提交)。 2、GET书签可收藏,POST为书签不可收藏。 3、GET能被缓存,POST不能缓存 。 4、GET编码类型application/x-www-form-url,POST编码类型encodedapplication/x-www-form-urlencoded 或 multipart/form-data。为二进制数据使用多重编码。 5、GET历史参数保留在浏览器历史中。POST参数不会保存在浏览器历史中。 6、GET对数据长度有限制,当发送数据时,GET 方法向 URL 添加数据;URL 的长度是受限制的(URL 的最大长度是 2048 个字符)。POST无限制。 7、GET只允许 ASCII 字符。POST没有限制。也允许二进制数据。 8、与 POST 相比,GET 的安全性较差,因为所发送的数据是 URL 的一部分。在发送密码或其他敏感信息时绝不要使用 GET ! 9、POST 比 GET 更安全,因为参数不会被保存在浏览器历史或 web 服务器日志中。 10、GET的数据在 URL 中对所有人都是可见的。POST的数据不会显示在 URL 中。 */