如何在Restlet 2.3.1中使用CORS?

如何在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 {

我正在尝试为响应设置“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 
    {
        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
    和一些带有
    POST
    的案例时。在这种情况下,执行跨域请求时不需要CORS头
  • 预飞请求需要CORS头进行跨域请求的其他情况
因此,如果您只是简单地执行一个方法
GET
,您什么也看不到是正常的。尝试使用带有JSON内容的方法
POST
,您将看到CORS标题

有关更多详细信息,请查看以下链接:

  • 理解和使用CORS-
已编辑

我为你的问题做了一个更完整的测试。我在不同的端口上启动了两个Restlet服务器(8182用于使用AJAX访问的资源,8183用于访问资源的JS应用程序)

第一个配置有您的代码:

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