2015-10-16 128 views
17

我在web应用工作包括UI的角度,服务器的Java,RestEasy的3.0.9.Final休息API调用否“访问控制允许来源”标头出现在所请求的资源 - RestEasy的

当我试图访问从另一个域中的其他服务我得到以下错误

无法加载回应预检要求未通过访问控制检查:没有“访问控制允许来源”标头出现在请求的资源。因此不允许访问原产地'http://localhost:8080'。

我配置我的服务器端与跨域调用作出反应,这正与GET呼叫,但POST调用正在创建错误

的web.xml

<context-param> 
    <param-name>resteasy.providers</param-name> 
    <param-value>com.test.sample.app.CorsFeature</param-value> 
</context-param> 

<listener> 
    <listener-class> 
     org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class> 
</listener> 


<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 

<servlet> 
    <servlet-name>resteasy-servlet</servlet-name> 
    <servlet-class> 
     org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class> 
    <init-param> 
     <param-name>javax.ws.rs.Application</param-name> 
     <param-value>com.test.sample.app.Application</param-value> 
    </init-param> 
</servlet> 

<servlet-mapping> 
    <servlet-name>resteasy-servlet</servlet-name> 
    <url-pattern>/rest/*</url-pattern> 
</servlet-mapping> 

<context-param> 
    <param-name>resteasy.servlet.mapping.prefix</param-name> 
    <param-value>/rest</param-value> 
</context-param> 
<context-param> 
    <param-name>resteasy.scan</param-name> 
    <param-value>true</param-value> 
</context-param> 

服务类

@GET 
@Path("/getnameAtt") 
@Produces(MediaType.APPLICATION_JSON) 
public Response getHostnameAttributes() { 
return Response 
.status(200) 
.header("Access-Control-Allow-Origin", "*") 
.header("Access-Control-Allow-Headers", 
     "origin, content-type, accept, authorization") 
.header("Access-Control-Allow-Credentials", "true") 
.header("Access-Control-Allow-Methods", 
     "GET, POST, PUT, DELETE, OPTIONS, HEAD") 
.header("Access-Control-Max-Age", "1209600") 
.entity(new TestImpl().getHostNameAttributes()) 
.build(); 
} 

@POST 
@Path("/getSeq") 
@Produces(MediaType.APPLICATION_JSON) 
public Response getCurrentSequence(String request) { 
return Response 
.status(200) 
.header("Access-Control-Allow-Origin", "*") 
.header("Access-Control-Allow-Headers", 
     "origin, content-type, accept, authorization") 
.header("Access-Control-Allow-Credentials", "true") 
.header("Access-Control-Allow-Methods", 
     "GET, POST, PUT, DELETE, OPTIONS, HEAD") 
.header("Access-Control-Max-Age", "1209600") 
.entity(new TestImpl().getCurrentSeq(request)) 
.build(); 
} 

由于我是新来的restea系统无法弄清楚为什么这不起作用。 任何帮助将不胜感激。等待你的答复。

谢谢

回答

8

您的资源方法不会被击中,所以他们的标题永远不会被设置。原因是在实际请求之前存在所谓的预检请求,这是一个OPTIONS请求。所以错误来自预检请求不会产生必要的标题的事实。

对于RESTeasy,您应该使用CorsFilter。有关示例,您可以看到here如何配置它。该过滤器将处理预检请求。所以你可以删除你的资源方法中的所有头文件。

另请参见:

+0

感谢您的回复。使用过CorsFilter并用@Provider注释。但是那个班甚至没有打电话。我是否需要在web.xml中添加任何内容 – user3595995

+0

如果您正在扫描资源,那么我链接的示例就是用于此目的。如果你明确地注册了所有的资源和提供者,那么你可以在'Application'类中注册'CorsFilter'。或者注册“特征”。无论哪种方式工作。虽然“特征”不是必需的。如果预检请求是显式的,还是由浏览器在内部处理,那么您可以在'Application'类 –

+0

中将'CorsFilter'注册到'getSingletons()'的重写中?在发送实际请求之前,是否必须先发送OPTION预检请求?我被困在类似的错误。 –

0

看来你的资源POST方法不会被打到的@peeskillet提。很可能你的〜POST〜请求不起作用,因为它可能不是一个简单的请求。唯一简单的请求是GET,HEAD或POST,并且请求头是简单的(唯一的简单头文件是Accept,Accept-Language,Content-Language,Content-Type = application/x-www-form-urlencoded,multipart/form-data ,text/plain)。

由于您已将Access-Control-Allow-Origin标题添加到您的回复中,因此您可以将新的OPTIONS方法添加到您的资源类中。

@OPTIONS 
@Path("{path : .*}") 
public Response options() { 
    return Response.ok("") 
      .header("Access-Control-Allow-Origin", "*") 
      .header("Access-Control-Allow-Headers", "origin, content-type, accept, authorization") 
      .header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD") 
      .header("Access-Control-Max-Age", "2000") 
      .build(); 
} 
相关问题