请求的资源上没有 'Access-Control-Allow-Origin' header - Resteasy

No 'Access-Control-Allow-Origin' header is present on the requested resource - Resteasy

我正在开发一个网络应用程序,包括 UI-Angular、Server-Java、RestEasy 3.0。9.Final 用于休息 api 调用

当我尝试从另一个域访问其余服务时出现以下错误

无法加载对预检请求的响应未通过访问控制检查:请求的资源上不存在 'Access-Control-Allow-Origin' header。因此不允许访问来源“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>

服务class

@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();
}

由于我是 resteasy 的新手,无法弄清楚为什么这不起作用。 任何帮助将不胜感激 。等待您的回复。

谢谢

您的资源方法不会被命中,因此它们的 headers 永远不会被设置。原因是在实际请求之前有所谓的预检请求,这是一个 OPTIONS 请求。所以错误来自于预检请求没有产生必要的 headers.

对于 RESTeasy,您应该使用 CorsFilter. You can see here 作为一些配置示例。此过滤器将处理预检请求。因此,您可以删除资源方法中的所有 headers。

另请参阅:

您的资源POST方法似乎不会像@peeskillet 提到的那样受到影响。您的 ~POST~ 请求很可能不会工作,因为它可能不是一个简单的请求。 The only simple requests are GET, HEAD or POST and request headers are simple(The only simple headers are Accept, Accept-Language, Content-Language, Content-Type= application/x-www-form-urlencoded, multipart/form-data, text/plain).

因为您已经将 Access-Control-Allow-Origin headers 添加到您的响应中,您可以将新的 OPTIONS 方法添加到您的资源 class.

    @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();
}

在遇到类似问题后,以下是我所做的:

  • 创建了一个 class 扩展 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>

最重要的代码 当我遇到这个问题时,我没有添加我的 class 扩展 javax.ws.rs.Application 即 RestApplication 到<servlet-name>resteasy-servlet</servlet-name>

的初始化参数
   <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>com.app.RestApplication</param-value>
    </init-param>

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