如何在Restlet 2.3.1中使用CORS?
我正在尝试为响应设置“Access Control Allow Origin:*”标题。但是,标题不存在。我做错了什么如何在Restlet 2.3.1中使用CORS?,cors,restlet,Cors,Restlet,我正在尝试为响应设置“Access Control Allow Origin:*”标题。但是,标题不存在。我做错了什么 public class JsonApplication extends Application { private static final String SERVER_URL = "http://localhost:8111"; public static void main(String[] args) throws Exception {
public class JsonApplication extends Application
{
private static final String SERVER_URL = "http://localhost:8111";
public static void main(String[] args) throws Exception
{
Server testServer = new Server(Protocol.HTTP, 8111);
JsonApplication jsonApplication = new JsonApplication();
CorsService corsService = new CorsService();
corsService.setAllowedOrigins( new HashSet(Arrays.asList("*")));
corsService.setAllowedCredentials(true);
jsonApplication.getServices().add( corsService );
testServer.setNext( jsonApplication );
testServer.start();
}
@Override
public Restlet createInboundRoot()
{
Router router = new Router( getContext() );
router.attach( SERVER_URL + "/", RootResource.class );
return router;
}
}
我检查了org.restlet.engine.application.CorsResponseHelper的源代码,其中包含以下代码:
public void addCorsResponseHeaders(Request request, Response response) {
String origin = request.getHeaders().getFirstValue("Origin", true);
if (origin == null) {
// Not a CORS request
return;
}
...
}
因此,当前CORS实现似乎不支持从本地html文件发出的请求,因为在这种情况下,origin==null
我在servlet应用程序中添加了一些日志记录:
JsonApplication::createInboundRoot()
16:26 MyCorsService()
16:26 myCorsService = wwwdbase.rest.cors.MyCorsService@6e1b241d
16:26 MyCorsService::setAllowedOrigins(), [*]
16:26 services: [org.restlet.service.TunnelService@4c88fe62,
org.restlet.service.StatusService@68349a5b,
org.restlet.service.DecoderService@77cfd8d3,
org.restlet.service.EncoderService@40c331fb,
org.restlet.service.RangeService@4bb3bc6f,
org.restlet.service.ConnectorService@7990100,
org.restlet.service.ConnegService@e194860,
org.restlet.service.ConverterService@578cfcb1,
org.restlet.service.MetadataService@18a62eb,
org.restlet.service.TaskService@4ed4f2db,
wwwdbase.rest.cors.MyCorsService@6e1b241d]
我们可以看到MyCorsService是可用的。但是,servlet框架从未调用它。另一方面,如果我从IDE运行服务(JavaSE版本),则调用MyCorsService。为什么这些案例表现不同
部分解决方案:通过更改org.restlet.engine.header.HeaderUtils中的代码,我成功地添加了allow origin头
if (response.getAccessControlAllowOrigin() != null)
{
addHeader(HeaderConstants.HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
response.getAccessControlAllowOrigin(), headers);
}
到
然而,Tomcat中的servlet框架为什么没有调用cors服务这个问题的答案仍然是未知的 事实上,您已经正确配置了Restlet的CORS服务;-) 在CORS的上下文中,有两种请求:
- 简单请求。简而言之,当您使用方法
、GET
和一些带有HEAD
的案例时。在这种情况下,执行跨域请求时不需要CORS头POST
- 预飞请求需要CORS头进行跨域请求的其他情况
GET
,您什么也看不到是正常的。尝试使用带有JSON内容的方法POST
,您将看到CORS标题
有关更多详细信息,请查看以下链接:
- 理解和使用CORS-
CorsService corsService = new CorsService();
corsService.setAllowedOrigins(new HashSet(Arrays.asList("*")));
corsService.setAllowedCredentials(true);
RestletApplication application = new RestletApplication();
application.getServices().add(corsService);
component.getDefaultHost().attachDefault(application);
其中的服务器资源很简单:
public class MyServerResource extends ServerResource {
@Get
public TestBean ping() {
TestBean bean = new TestBean();
bean.setMessage("pong");
return bean;
}
}
第二个应用程序仅使用Restlet目录来提供静态内容:
@Override
public Restlet createInboundRoot() {
Router router = new Router(getContext());
router.attach("/static", new Directory(
getContext(), "clap:///test/static"));
return router;
}
除了JQuery库,我还添加了以下HTML文件:
<html>
<head>
<script type="text/javascript" src="/static/jquery-1.11.2.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#id1').click(function() {
$.ajax({
url : 'http://localhost:8182/ping',
type : 'GET',
success : function(result, status){
console.log('ok = '+result);
},
error : function(result, status, error){
console.log('error');
},
complete : function(result, status){
console.log('complete');
}
});
});
});
</script>
</head>
<body>
<div id="id1">Click</div>
</body>
</html>
如您所见,COR存在;-)
希望它能帮助你,
蒂埃里谢谢你的回答。我正在开发一个RESTful服务,它以JSON格式返回数据。客户机可以开发自己的基于浏览器的UI,并使用AJAX调用与服务器交互。默认情况下禁止跨域AJAX调用,因此即使使用GET,也需要CORS(或JSONP)。但是,我通过将请求url直接写入浏览器的地址栏来测试服务器调用。显然,这不是一个正确的AJAX调用,因此不奇怪是否缺少头。我隐式地假设,如果CORS配置正确,Restlet框架总是包含标题…我用一个更完整的测试编辑了我的答案。似乎在AJAX请求中,CORS头就在那里;-)我现在已经在本地主机Tomcat服务器下安装了我的应用程序。如果我通过jqueryajax从本地html文件调用该服务,我会得到响应:“跨源请求被阻止:同源策略不允许读取远程资源”。这可以通过将资源移动到同一个域或启用CORS来解决。所以,CORS似乎不起作用!?在基于html文件的调用中,有一个请求头“originnull”。也许这就是问题的根源。如果是,如何解决?请编辑此答案,它具有误导性。“简单请求”还需要CORS标题,您的链接博客帖子证实了这一点。
<html>
<head>
<script type="text/javascript" src="/static/jquery-1.11.2.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#id1').click(function() {
$.ajax({
url : 'http://localhost:8182/ping',
type : 'GET',
success : function(result, status){
console.log('ok = '+result);
},
error : function(result, status, error){
console.log('error');
},
complete : function(result, status){
console.log('complete');
}
});
});
});
</script>
</head>
<body>
<div id="id1">Click</div>
</body>
</html>
// Request
Accept */*
Accept-Encoding gzip, deflate
Accept-Language fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3
Host localhost:8182
Origin http://localhost:8183
Referer http://localhost:8183/static/test.html
User-Agent Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:36.0) Gecko/20100101 Firefox/36.0
// Response
Accept-Ranges bytes
Access-Control-Allow-Cred... true
Access-Control-Allow-Orig... http://localhost:8183
Content-Type application/json
Date Fri, 13 Mar 2015 09:16:48 GMT, Fri, 13 Mar 2015 09:16:48 GMT
Server Restlet-Framework/2.3.1
Transfer-Encoding chunked
Vary Accept-Charset, Accept-Encoding, Accept-Language, Accept