在构建分布式系统时,将门户系统(负责前端页面展示的控制器)和获取数据的系统(从数据库获取资料)分开。在开发过程中,会遇到跨域请求问题。
跨域是指一个域下的文档或脚本试图去请求另一个域下的资源,这里跨域是广义的。
<link>
、<script>
、<img>
、<frame>
等 dom 标签,还有样式中background:url()、@font-face()等文件外链其实我们通常所说的跨域是狭义的,是由浏览器同源策略限制的一类请求场景。主要特征有两种:
域名不相同,即两个不同的应用
域名相同,但是端口不同,即同一个应用中的不同子系统
想要从数据系统的接口中获得数据,我常用的有两种方式:
通常为了减轻 web 服务器的负载,我们把js、css,img 等静态资源分离到另一台独立域名的服务器上,在 html 页面中再通过相应的标签从不同域名下加载静态资源,这种行为被浏览器允许。基于此原理,我们可以把需要的数据封装成一段 js 代码。
jsonp 只能使用 get 请求,前台请求时,指定回调函数名,后台系统将数据封装成 js 代码,将数据放到参数里面:
callback(数据)
前台 javascript 里准备好对应的回调函数操作数据,或在 ajax 中用 success 的 function 去接受参数,并操作数据。示例如下:
/* 8081 端口的服务器有一静态资源 test.json,现在需要从 8080 的服务器去获得并显示到页面上。这里将数据修改,封装成 js: callback({"data":"helloworld", "status":"200"}) */ $.ajax({ url: "http://localhost:8081/test.json", type: "get", datatype: "jsonp", //jsonp请求 jsonp: "callbackfunction", //请求参数名 jsonpcallback: "callback", //回调函数名称,也可以直接用 success 接受参数 /*success: function (data) { $('#text').val(json.stringify(data)); }*/ }) function callback(data) { $('#text').val(json.stringify(data)); }
httpclient 是 apache jakarta common 下的子项目,用来提供高效的、最新的、功能丰富的支持 http 协议的客户端编程工具包,并且它支持 http 协议最新的版本和建议。实现了所有 http 的方法(get,post,put,head 等)。在 java 代码中,可以通过它发送 http 请求,通常用来实现远程接口调用。
maven 中需要的依赖:
<dependency> <groupid>org.apache.httpcomponents</groupid> <artifactid>httpclient</artifactid> </dependency>
//无参数 get 请求 @test public void doget() { //创建 httpclient 对象 closeablehttpclient httpclient = httpclients.createdefault(); //创建 get 请求 httpget httpget = new httpget("http://www.baidu.com/"); closeablehttpresponse response = null; try { //执行请求 response = httpclient.execute(httpget); //输出请求状态 system.out.println(response.getstatusline()); //判断请求状态并输出响应内容 if (response.getstatusline().getstatuscode() == 200){ //使用工具将响应实体字符串化 string content = entityutils.tostring(response.getentity()); system.out.println("content:\n" + content); } } catch (clientprotocolexception e) { e.printstacktrace(); } catch (ioexception e) { e.printstacktrace(); } finally { if (null != response) { try { response.close(); } catch (ioexception e) { e.printstacktrace(); } finally { if (null != httpclient) { try { httpclient.close(); } catch (ioexception e) { e.printstacktrace(); } } } } } } //get请求带参数 @test public void dogetwithparam() { closeablehttpclient httpclient = httpclients.createdefault(); closeablehttpresponse response = null; try { //定义请求的参数,使用 uribuilder 工具创建 uri uri = new uribuilder("http://www.baidu.com/s").setparameter("wd", "你好世界").build(); system.out.println("uri: " + uri); //创建请求对象 httpget httpget = new httpget(uri); //execute response = httpclient.execute(httpget); //判断响应状态 if (response.getstatusline().getstatuscode() == 200) { system.out.println(entityutils.tostring(response.getentity())); } } catch (ioexception e) { e.printstacktrace(); } catch (urisyntaxexception e) { e.printstacktrace(); } finally { if (null != response) { try { response.close(); } catch (ioexception e) { e.printstacktrace(); } finally { if (null != httpclient) { try { httpclient.close(); } catch (ioexception e) { e.printstacktrace(); } } } } } } //post 请求 @test public void post() { //创建 httpclient 对象 //closeablehttpclient httpclient = httpclientbuilder.create().setredirectstrategy(new laxredirectstrategy()).build(); closeablehttpclient httpclient = httpclients.createdefault(); //创建 post 请求 httppost httppost = new httppost("http://localhost:8080/item/536563"); closeablehttpresponse response = null; try { //执行请求 response = httpclient.execute(httppost); system.out.println(response.getstatusline()); if (response.getstatusline().getstatuscode() == 200) { system.out.println(entityutils.tostring(response.getentity())); } } catch (clientprotocolexception e) { e.printstacktrace(); } catch (ioexception e) { e.printstacktrace(); } finally { if (null != response) { try { response.close(); } catch (ioexception e) { e.printstacktrace(); } finally { if (null != httpclient) { try { httpclient.close(); } catch (ioexception e) { e.printstacktrace(); } } } } } } //执行 post 请求带参数 @test public void postwithparam() throws ioexception { closeablehttpclient httpclient = httpclients.createdefault(); httppost httppost = new httppost("http://localhost:8080/item/cat/list"); //可以设置多个参数 arraylist<namevaluepair> parameters = new arraylist<>(); parameters.add(new basicnamevaluepair("id", "2")); //将参数集合封装成请求实体 urlencodedformentity entity = new urlencodedformentity(parameters); //将请求实体放入请求中 httppost.setentity(entity); //执行请求 closeablehttpresponse response = httpclient.execute(httppost); //输出结果 system.out.println(response.getstatusline()); if (response.getstatusline().getstatuscode() == 200) { system.out.println(entityutils.tostring(response.getentity())); } //关闭资源 if (null != response) { try { response.close(); } catch (ioexception e) { e.printstacktrace(); } finally { if (null != httpclient) { try { httpclient.close(); } catch (ioexception e) { e.printstacktrace(); } } } } }
设置请求的编码格式:
obj.addheader("content-type","application/x-www-form-urlencoded; charset=utf-8");
网站设置了反爬虫机制,禁止非法访问,可以通过伪装成浏览器解决。
obj.addheader("user-agent"," mozilla/5.0 (windows nt 6.1) applewebkit/537. 36 (khtml, like gecko) chrome/31.0.1650.63")
如对本文有疑问, 点击进行留言回复!!
springcloud中feign调用处理mybatis-plus Ipage反序列化问题。
Flume 史上最全面的大数据学习第十篇(一) 别再说不知道flume是什么了
网友评论