跨域

什么是跨域

浏览器对js的安全限制(即同源策略)不允许跨域访问,即当前浏览器不能访问满足以下条件的资源

  • IP不同(和当前浏览器,以下同)
  • 协议不同(如http和https)
  • 域名不同
  • 域名相同,但端口不同

为什么要跨域

同一产品的不同前端系统(如PC端,安卓端,ios等)需要的业务逻辑相似
为了提高代码复用率,避免为每一种前端系统项目都开发一套相似的业务逻辑代码
专门开发一个后端系统项目来实现业务逻辑,让多个前端系统共同调用即可

优点缺点
提高代码复用率需要发布Webservice
提高可扩展性系统之间需要远程调用
降低耦合度

跨域的实现

一、项目准备

准备两类项目,两者间通过Webservice进行通信

项目类别项目个数项目特点项目组成
服务层一个没有表现层,只有业务逻辑,需要连接数据库,需要发布服务controller,service,pojo,dao
表现层一个或多个有表现层,没有业务逻辑,不需连接数据库controller,service,pojo,jsp
二、解决跨域
方法请求数据时间实现方式
jsonp页面加载完毕之后(js代码在页面加载完毕后执行)前端ajax跨域访问js片段 (动态加载数据,网页更新少,活跃度低,不利于搜索引擎优化)
HttpClient页面初始化时在service层用CloseableHttpClient类发送跨域请求,在controller层用addAttribute为对应的视图中的参数赋值

jsonp:

jsonp跨域的原理:js不能跨域访问数据,但可以跨域访问js片段
使用<script>标签,标签中指定src=需要跨域访问的资源地址
或者将数据用js方法包装后在url中传递callback参数回调该方法

  • 客户端在请求资源的url后传递一个callback参数,参数值为回调方法的名称

    url = "资源路径?callback=回调方法名称";
    
  • 在客户端用jsonp发送请求

    $.getJSONP(url);
    
  • 在服务端用回调方法将数据包装成js片段,以getData(data)的形式返回数据

    //方法一
    @RequestMapping(value = "资源路径", produces = MediaType.APPLICATION_JSON_VALUE+";charset=utf-8")
    @ResponseBody
    private String getItemCatList(String callback) {
    	//取数据
    	ItemCatResult itemCatResult = itemCatService.getItemCatList();
    	
    	//支持jsonp调用
    	String json = JsonUtils.objectToJson(itemCatResult);
    	return "callback("+json+")";
    }
    
    //方法二
    @RequestMapping("资源路径")
    @ResponseBody
    private Object getItemCatList(String callback) {
    	//取数据
    	ItemCatResult itemCatResult = itemCatService.getItemCatList();
    	
    	//支持jsonp调用
    	MappingJacksonValue mappingJacksonValue = new MappingJacksonValue(itemCatResult);
    	mappingJacksonValue.setJsonpFunction(callback);
    	return mappingJacksonValue;
    }
    

HttpClient:
在service层用java代码模拟浏览器跨域请求数据

  • 准备:在项目中添加依赖的jar包:httpclient、httpcore
  • 模拟get请求数据:
    public void testHttpGet() throws Exception {
    	
    	//创建HttpClient对象来准备发送请求
    	CloseableHttpClient httpClient = HttpClients.createDefault();
    	//创建httpGet设置访问的url地址
    	HttpGet httpGet = new HttpGet("http://www.baidu.com");
    	//执行请求,创建httpRespond
    	CloseableHttpResponse httpResponse = httpClient.execute(httpGet);
    	//创建httpentity接收返回数据
    	HttpEntity entity = httpResponse.getEntity();
    	//转化接收数据格式
    	String html = EntityUtils.toString(entity, "UTF-8");
    	System.out.println(html);
    	//关闭请求、关闭响应
    	httpResponse.close();
    	httpClient.close();
    }
    
  • 模拟post请求数据:
    public void testHttpPost() throws Exception {
    	
    	//创建HttpClient对象来准备发送请求
    	CloseableHttpClient httpClient = HttpClients.createDefault();
    	//创建httpPost设置访问的url地址
    	HttpPost httpPost = new HttpPost("http://localhost:8082/posthtml.html");
    	//准备需要发送的数据
    	List<NameValuePair> list = new ArrayList<>();
    	list.add(new BasicNameValuePair("name","张三"));
    	list.add(new BasicNameValuePair("pass","123"));
    	//创建StringEntity将需要发送的数据包装
    	StringEntity entity = new UrlEncodedFormEntity(list, "UTF-8");
    	//将包装好的数据添加到请求中
    	httpPost.setEntity(entity);
    	//发送请求,创建httpResponse接收请求响应
    	CloseableHttpResponse httpResponse = httpClient.execute(httpPost);
    	//创建httpEntity从响应中取出返回数据
    	HttpEntity httpEntity = httpResponse.getEntity();
    	//用EntityUtils转化接收数据格式
    	String res = EntityUtils.toString(httpEntity,"UTF-8");
    	System.out.println(res);
    	//关闭响应、请求
    	httpResponse.close();
    	httpClient.close();
    }
    
  • 给前端页面赋值:
    @RequestMapping("/index")
    public String showIndex(Model model) {
    	//获取跨域请求返回的数据
    	String adData = contentService.getAd1List();
    	//传递给前端页面
    	model.addAttribute("adData",adData);
    	//返回指定的前端页面视图
    	return "index";
    }
    

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值