否';访问控制允许原点';请求的资源上存在标头-Resteasy

否';访问控制允许原点';请求的资源上存在标头-Resteasy,rest,cors,resteasy,Rest,Cors,Resteasy,我正在开发一个Web应用程序,它包括UI、服务器Java、RestEasy 3.0.9.Final,用于rest api调用 当我试图从另一个域访问rest服务时,出现以下错误 无法加载对飞行前请求的响应未通过访问控制检查:请求的资源上不存在“访问控制允许来源”标头。因此,不允许对源“”进行访问。 我将服务器端配置为使用跨域调用进行响应,这可以使用GET调用,但POST调用正在创建错误 web.xml <context-param> <param-name>res

我正在开发一个Web应用程序,它包括UI、服务器Java、RestEasy 3.0.9.Final,用于rest api调用

当我试图从另一个域访问rest服务时,出现以下错误

无法加载对飞行前请求的响应未通过访问控制检查:请求的资源上不存在“访问控制允许来源”标头。因此,不允许对源“”进行访问。

我将服务器端配置为使用跨域调用进行响应,这可以使用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>
因为我是刚接触resteasy的人,所以无法理解为什么这不起作用。 任何帮助都将不胜感激。等待您的回复


谢谢

您的资源方法不会被命中,因此它们的头永远不会被设置。原因是在实际请求之前有所谓的飞行前请求,这是一个
OPTIONS
请求。因此,错误来自飞行前请求没有生成必要的头的事实

为了方便起见,您应该使用。您可以查看如何配置它的一些示例。此筛选器将处理飞行前请求。因此,您可以删除资源方法中的所有头文件

另请参见:


看来你的资源
POST
方法不会像@peeskillet提到的那样受到攻击。您的~POST~请求很可能不起作用,因为它可能不是一个简单的请求。唯一的简单请求是GET、HEAD或POST,请求头是simple(唯一的简单头是Accept、Accept Language、Content Language、Content Type=application/x-www-form-urlencoded、multipart/form data、text/plain)

由于您已经在响应中添加了
accesscontrolalloworigin
标题,因此可以向资源类添加新的
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();
}

在面临类似问题后,我做了如下工作:

  • 创建了一个扩展javax.ws.rs.core.Application的类,并向其中添加了Cors过滤器
在CORS过滤器中,我添加了
corsFilter.getAllowedOriginates().add(“http://localhost:4200");

基本上,您应该添加允许跨源资源共享的URL。Ans您也可以使用
“*”
而不是任何特定的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;
    }
}
公共类重新应用程序
扩展应用程序
{
private Set singleton=new HashSet();
公共消息应用程序()
{
singletons.add(new CalculatorService());//CalculatorService是您要添加/使用的特定服务。
CorsFilter CorsFilter=新的CorsFilter();
//要允许CORS的所有来源,请添加以下内容,否则仅添加特定URL。
//corsFilter.getAllowedOriginates().add(“*”);
System.out.println(“仅允许重新引用URL”);
corsFilter.getAllowedOriginates().add(“http://localhost:4200");
Singleton=新LinkedHashSet();
添加(corsFilter);
}
@凌驾
公共集getSingleton()
{
返回单身人士;
}
}
  • 这是我的web.xml:

Restful Web应用程序
轻松扫描
真的
resteasy.servlet.mapping.prefix
/休息
org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
RESTEasyServlet
org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
javax.ws.rs.Application
com.app.RestApplication
RESTEasyServlet
/休息/*
当我遇到这个问题时,最重要的代码是,我没有将扩展javax.ws.rs.Application的类(即RestApplication)添加到
resteasy servlet的init参数中


javax.ws.rs.Application
com.app.RestApplication

因此我的筛选器无法执行,因此应用程序不允许来自指定URL的COR。

感谢您的响应。已使用该CorsFilter并用@Provider注释。但这个类甚至没有被称为。如果您正在扫描资源,我是否需要在web.xml中添加我链接到的示例。如果显式注册所有资源和提供者,则只需在
应用程序
类中注册
CorsFilter
。或注册
功能
。两种方法都有效。但是不需要
功能
。您可以在
应用程序的
类中的
getsingleton()
覆盖中注册
CorsFilter
,飞行前请求是显式的还是由浏览器内部处理的?在发送实际请求之前,我是否必须先发送选项飞行前请求?我也遇到了类似的错误。@SudipBhandari否对于任何需要跨源检查的请求,浏览器都会透明地处理整个交互。您只需要将服务器设置为处理飞行前的选项(通过发送适当的CORS响应头)。这篇文章中提到的
CorsFilter
就是这样做的。@peeskillet那么,如果我要发布一个API,该API也应该处理飞行前的选项吗?我问这个问题是因为通过邮递员这样的客户做出的回应是可以的。我的post请求中有自定义标题,但仍然无法通过访问控制检查。此外,chrome控制台中的错误消息是“无访问控制允许源站存在”,尽管它显然是存在的,否则“邮递员”之类的东西将如何成功接收响应。帮帮我
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-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>
   <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>com.app.RestApplication</param-value>
    </init-param>