请求的资源上没有“Access-Control-Allow-Origin”标头 - Resteasy

时间:2015-10-16 07:16:02

标签: rest cors resteasy

我正在开发一个web应用程序,包括UI-Angular,Server-Java,RestEasy 3.0.9.Final for rest api calls

当我尝试从其他域访问其他服务时,我遇到错误

CAN NOT LOAD对预检请求的响应未通过访问控制检查:请求的资源上没有“Access-Control-Allow-Origin”标头。因此,不允许原点“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();
}

因为我是新来的,不能弄清楚为什么这不起作用。 任何帮助将不胜感激 。等待你的回复。

由于

3 个答案:

答案 0 :(得分:11)

您的资源方法不会被命中,因此它们的标题永远不会被设置。原因是在实际请求之前存在所谓的预检请求,即OPTIONS请求。因此,错误来自于预检请求不会产生必要的标题。

对于RESTeasy,您应该使用CorsFilter。您可以查看here的一些示例,了解如何配置它。此过滤器将处理预检请求。因此,您可以删除资源方法中的所有标题。

另见:

答案 1 :(得分: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();
}

答案 2 :(得分:0)

遇到类似问题后,下面是我的操作:

  • 创建了一个扩展javax.ws.rs.core.Application的类,并向其添加了Cors过滤器。

在CORS过滤器中,我添加了corsFilter.getAllowedOrigins().add("http://localhost:4200");

基本上,您应该添加要允许跨域资源共享的URL。也可以使用"*"代替任何特定的URL来允许任何URL。

public class RestApplication
    extends Application
{
    private Set<Object> singletons = new HashSet<Object>();

    public MessageApplication()
    {
        singletons.add(new CalculatorService()); //CalculatorService is your specific service you want to add/use.
        CorsFilter corsFilter = new CorsFilter();
        // To allow all origins for CORS add following, otherwise add only specific urls.
        // corsFilter.getAllowedOrigins().add("*");
        System.out.println("To only allow restrcited urls ");
        corsFilter.getAllowedOrigins().add("http://localhost:4200");
        singletons = new LinkedHashSet<Object>();
        singletons.add(corsFilter);
    }

    @Override
    public Set<Object> getSingletons()
    {
        return singletons;
    }
}
  • 这是我的web.xml:
<web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>Restful Web Application</display-name>

    <!-- Auto scan rest service -->
    <context-param>
        <param-name>resteasy.scan</param-name>
        <param-value>true</param-value>
    </context-param>

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

    <listener>
        <listener-class>
            org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
        </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.app.RestApplication</param-value>
        </init-param>
    </servlet>

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

</web-app>

我遇到此问题时最想念的最重要的代码是,我没有添加扩展javax.ws.rs.Application的类,即RestApplication到{{ 1}}

<servlet-name>resteasy-servlet</servlet-name>

因此我的过滤器无法执行,因此应用程序不允许通过指定的URL进行CORS。