请求的资源上没有 '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。
我正在开发一个网络应用程序,包括 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。