JavaScript > 使用JSONP或HttpClient跨域请求

什么是跨域?
判断是否跨域,就是看协议+域名+端口是否相同,因为绝大多数网站使用默认的端口80,所以通常比较协议+域名。比如http://www.abc.com/a/b.js 中需要请求http://www.cba.com/invest/totalAmout 获取投资总额。

使用jsonp跨域

jsonp主要是通过script可以链接远程url来实现跨域请求的。如:

<script src="http://jsonp.js?callback=xxx"></script>

先看一个使用jsonp跨域请求的例子:

$.ajax({ url: 'http://localhost:8980/bankwelp2p-jsonp/totalInvest?callback=?', type: 'GET', dataType: "jsonp", cache: false, success: function(data){ alert(data.value); }
});

这段jQuery代码向http://localhost:8980/bankwelp2p-jsonp/totalInvest发起一个get类型的ajax请求,期望返回的数据类型是jsonp。那么url后缀参数callback=?是什么意思呢?

callback=?是告诉接收方装载回调函数名的参数是callback,回调函数值是=?表示jQuery会替换为自动生成的函数名,比如jQuery182014784806407988071_1452761203259。所以实际请求参数是:http://localhost:8980/bankwelp2p-jsonp/totalInvest?callback=jQuery182014784806407988071_1452761203259&_=1452761399353

接收方如何处理呢?下面是一段示例代码:

@RequestMapping(value = "totalInvest" )
public @ResponseBody
String getTotalInvest(@RequestParam String callback){
    String totalInvest = "" ;
     try {
        Map<String, Object> result = new HashMap<>();
        result.put( "value" , "2000");
        totalInvest = CStringUtils.getJSONPCallback(callback, result);
    } catch (Exception e) {
        LoggerUtils.error(e);
    }
     return totalInvest;
}

CStringUtils.java

public static String getJSONPCallback(String callback , ObjectjsonObject) throws Exception {
  return callback + "(" + serializeToJson( jsonObject) + ")" ;
}

可见,接收方只是把回调函数名和应答json串拼装起来,组成jQuery182015939638670533895_1452765251401({“value”:”2000”})这样的字符串,返回给请求方。

对于jQuery自动生成的回调函数名,回调动作由success:function(data){}函数处理,断点模式下可以看到data值为:data = Object{value:”2000”},接下来就可以通过data.value来使用返回的数据了。

可以通过设置jsonpCallback参数指定一个回调函数名,比如设置为xxx,同时定义一个function xxx(data){},这样回调时首先经过xxx函数,但依然会进入success:function(data),这样看设置jsonpCallback就没有什么意义了。

用httpclient跨域

比如要请求另一域名下的某个方法,促使该域名下的应用重新加载系统参数。使用HttpGet发请求的代码如下:

public boolean notifyWebOfReloadingSysParams() {
    CloseableHttpClient httpclient = null;
    try {
        httpclient = HttpClients.createDefault();
        HttpGet httpget = new HttpGet("http:/localhost:8080/demo/common/reloadSysParams");
        // Create a custom response handler
        ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
            @Override
            public String handleResponse(final HttpResponse response)
                throws ClientProtocolException, IOException {
                int status = response.getStatusLine().getStatusCode();
                if(status == 200){
                    HttpEntity entity = response.getEntity();
                    return entity != null ? EntityUtils.toString(entity) : null;
                }
                return null;
                }
            };
            String responseBody = httpclient.execute(httpget, responseHandler);
            return "success".equals(responseBody);
    } catch (Exception e) {
        LoggerUtils.error(e);
    } finally {
        if(httpclient != null){
            httpclient.close();
        }
    }
}

另一域名下接收请求的方法:

    /** * @Description:重新加载系统参数 * @Author:tony * @Since:2016年1月19日 * @return */
    @RequestMapping(value = "reloadSysParams")
    public @ResponseBody String reloadSysParams(){
        try{
            config.loadSysParams();
        }catch(Exception e){
            LoggerUtils.error(e);
            return "fail";
        }
        return "success";
    }

你可能感兴趣的:(JavaScript > 使用JSONP或HttpClient跨域请求)