zoukankan      html  css  js  c++  java
  • 优雅的封装ajax,含跨域

    之前写过一篇 先定一个小目标,自己封装个ajax,是基于原生js的,也就是jquery中ajax的简化版本实现的思路。众所周知,jquery的ajax是项目中最常用的请求后台的方式,也算是封装的很完美的api了,然而渐渐的我们会发现,其实还可以根据实际项目需要更优雅的进行一层封装,先看调用方式:

    熟悉EasyUI的猿们可能会觉得这种方式有点熟悉,没错,我就是看easyUI得到的启发,也显然这样的方式更利于前端做判断,逻辑更清晰明了。那么代码后面是怎样封装的呢,我这里贴出核心的代码以及思路。

    思路

    将后台返回的不同业务状态码以函数回调的形式代替,减少if的多层级判断。同时将通用的错误状态码逻辑(如这里的900状态是通用异常)、通用的请求参数(如client客户端来源,是否需要token证书)、请求前置触发操作(如加载中动画)等等进行统一处理,既减少的代码量,同时又更利于维护。

    封装的js代码

    
    var LI = {
        //发送get请求
        GET: function(options){
            this.ajax(options,'get');
        },
        //发送post请求
        POST: function(options){
            this.ajax(options,'post');
        },
        ajax: function(options,type){
            var opts = {
                isCommonBefore: true, //默认是通用的加载中动画
                client: 1, //TODO这里应该根据内核判断
                isCors: false,//默认不跨域
                isLogin: false
            }
            
            $.extend(true, options, opts || {});
            
            //跨域,将请求地址 和 请求参数 都作为参数传递调用后台固定的跨域接口
            if (opts.isCors) {
                opts.data = {
                    url: opts.url,//真实的url
                    params: JSON.stringify(opts.data), //请求参数
                }
                opts.url = URL.CORS;
            }
            
            //添加默认的参数
            opts.data.client = opts.client;
            //需要登录认证的请求
            if(opts.isLogin){
                opts.data.token = LI.getToken()
            }
            
            $.ajax({
                url: opts.url,
                data: opts.data,
                type: type,
                async: opts.async,
                beforeSend: function() {
                    opts.isCommonBefore ? LI.loadingShow() : (opts.beforeSend && opts.beforeSend())
                },
                success: function(json) {
                    if(json){
                        console.log(opts.baseUrl || opts.url,' ajax is successful',json);
                        opts.success && opts.success(json);
    
                        if(opts[json.status]){//区分不同的状态码回调函数
                            console.log(opts.baseUrl || opts.url,'ajax status is', json.status, '并已回调'+ json.status +'方法');
                            eval(opts[json.status])(json);
                        }
                    }else{
                        console.error(opts.baseUrl || opts.url,'ajax 数据返回格式异常');
                        LI.ajaxError();
                    }
                },
                error: function(){
                    console.error(opts.baseUrl || opts.url,' ajax is error');
                    opts.error != undefined ? opts.error() : LI.commonError();
                },
                complete: function(XMLHttpRequest, textStatus) {
                    console.log(opts.baseUrl || opts.url,' ajax is complete');
                },
                timeout: opts.timeout || 20000
            })
        }
    }
    

    核心是这一句 eval(opts[json.status])(json); 将状态码转换成回调函数,并将json对象传进去。

    调用

    LI.POST({
        url: LI_ENV.URL.BASE + LI_ENV.API.doPrayerSquareLike,
        data: {
            prayerSquareId: LI.getUrlParameter('id')
        },
        isLogin: true,
        //isCors: true,//如跨域设置true即可
        600: function(json){
            console.log("点赞成功");
        },
        803: function(){
            console.log('请登录后操作');
        },
        609: function(){
            console.log('已点赞');
        }
    })
    

    跨域Controller

    @RequestMapping(value = "cors", method = {RequestMethod.GET,RequestMethod.POST})
    @ResponseBody
    public commonResult cors(@RequestParam String url,
    					   @RequestParam(required=false) String params,
    					   HttpServletRequest request, 
    					   HttpServletResponse response) throws IOException, URISyntaxException {
    	LOGGER.info("The request of cors,url:{},params:{}",url,params);
    	boolean isGet = request.getMethod().toLowerCase().equals("get");
    	Map<String, String> map = new HashMap<String, String>();
    
    	if (!StringUtils.isBlank(params)) {
    		//有序遍历
    		LinkedHashMap<String, String> jsonMap = JSON.parseObject(params, new TypeReference<LinkedHashMap<String, String>>() {
            });
            for (Map.Entry<String, String> entry : jsonMap.entrySet()) {
                map.put(entry.getKey(), entry.getValue());
            }
    	}
    	
    	String result = null;
    	try {
    		
        	if (isGet) {
    			result = apiService.doGet(MANAGE_URL + url, map);
    		}else{
    			HttpResult hr = apiService.doPost(MANAGE_URL + url, map);
    			result = hr.getData();
    		}
        	
        	JSONObject obj = JSONObject.parseObject(result);
        	
        	try {
        		Integer status = obj.getInteger("status");
        		String msg = obj.getString("msg");
            	return new commonResult(status, msg, obj.get("data"));
    		} catch (Exception e) {
    			return commonResult.fail();
    		}
    	} catch (Exception e) {
    		return commonResult.fail();
    	}
    }
    

    核心代码如上,得到前端传上来的url,以及解析params,再通过httpClient的形式请求真正的后台地址,其中doPost方法来自 ApiUtil

    同时跨域也可以参考以前的文章 jsonp跨域请求

  • 相关阅读:
    IList扩展
    WPF 路由事件
    WPF 属性值绑定、转换
    WPF 生命周期
    App.config 动态编辑
    Oracle Package的全局变量与Session
    AES对数据进行加密与解密
    OracleAES加密
    AES加解密程序的实现
    Oracle的AES加密与解密用法
  • 原文地址:https://www.cnblogs.com/liliangel/p/7155212.html
Copyright © 2011-2022 走看看