我试图连接到使用JAX-RS构建的RESTendpoint,但得到的响应是头'access-control-allow-origin'不存在。试图获取Angular2的资源。
我所尝试的
我尝试了https://stackoverflow.com/A/30450944中提供的解决方案。
我的响应筛选器:
@Provider
@PreMatching
public class ResponseFilter implements ContainerResponseFilter {
@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
responseContext.getHeaders().add("Access-Control-Allow-Origin", "*");
responseContext.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
responseContext.getHeaders().add("Access-Control-Allow-Credentials", "true");
responseContext.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
}
}
和我的web.xml servlet映射:
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>com.api.ResponseFilter</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
更新1
更新了
responseContext.getHeaders().add(...);
至
responseContext.getHeaders.putSingle(...);
但我还是会犯同样的错误。在postman中进行测试时,我得到了正确的邮件头:
Access-Control-Allow-Credentials →true
Access-Control-Allow-Headers →origin, content-type, accept, authorization
Access-Control-Allow-Methods →GET, POST, PUT, DELETE, OPTIONS, HEAD
Access-Control-Allow-Origin →*
更新2
在扩展应用程序的JAXRSConfig中,我手动添加了所有可能需要的资源:
@ApplicationPath("api")
public class JAXRSConfig extends Application {
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> resources = new HashSet<>();
addRestResourceClasses(resources);
return resources;
}
private void addRestResourceClasses(Set<Class<?>> resources) {
resources.add(AdminResource.class);
resources.add(RequestFilter.class);
resources.add(ResponseFilter.class);
resources.add(TweetResource.class);
resources.add(UserResource.class);
}
}
通过使用断点,我注意到当我通过Postman发送get请求时,我的ResponseFilter确实会被调用,但当我通过angular应用程序发送get请求时,它不会被调用。
我的角码发送请求:
let headers = new Headers({'Authorization': authToken});
headers.append('Content-Type', 'application/json');
let options = new RequestOptions({ headers: headers});
return this.http.get(http://localhost:8080/api/object/user)
.map((res:Response) => res.json())
.catch((error:any) => Observable.throw(error.json().error || 'Server error'));
更新3
我确实意识到我实际上并没有将定义的头添加到请求中;所以我更新了angular代码:
let authToken = "Basic " + btoa("henk:asdf");//temporary until I learn how to allow a user to log in, in angular
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Authorization', authToken);
//let options = new RequestOptions({ headers: headers});
return this.http.get(this.myUrl, {headers: headers})
.map((res:Response) => res.json())
.catch((error:any) => Observable.throw(error.json().error || 'Server error'));
更新4
从那以后,我了解到这可能是由于Chrome(和其他浏览器)通过一个名为Options的请求方法执行的飞行前检查。我在api中添加了一个请求过滤器,如下所示:
@Provider
@PreMatching
public class RequestFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
if (requestContext.getRequest().getMethod().equals("OPTIONS")) {
requestContext.abortWith(Response.status(Response.Status.OK).header("Access-Control-Allow-Origin", "http://localhost:4200").build());
}
}
}
但没有用。在if语句上有一个断点,我看到这个方法不会从angular的get请求中调用,但会从Postman的请求中调用。
我还根据https://stackoverflow.com/a/19902666/6795661尝试了一个不同的CORS过滤器。但这也没有奏效。
更新5
根据peeskillet,我尝试创建一个实现javax.servlet.filter的类,以便将所需的头添加到响应中:
public class ContainerResponseFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse) response;
res.addHeader("Access-Control-Allow-Origin", "http://localhost:4200");
res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
res.addHeader("Access-Control-Allow-Headers", "Content-Type");
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
与my web.xml中相应的映射:
<filter>
<filter-name>corsfilter</filter-name>
<filter-class>com.api.ContainerResponseFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>corsfilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
并且我在应用程序配置中添加了ContainerResponseFilter作为资源。不幸的是,我仍然得到的错误是'access-control-allow-origin'头不存在。
事实证明,问题出在身份验证上。我的应用程序服务器试图验证请求,但是由于在验证之前进行了CORS检查,我只是得到了一个未经授权的响应,其中不包括所需的头。
问题内容: 我已经集成了带角度应用程序的按键斗篷。基本上,前端和后端都在不同的服务器上。后端应用程序在Tomcat 8上运行。前端应用程序在JBoss欢迎内容文件夹上运行。 角度配置 请求标题 Web控制台错误。 后端的Cors筛选器 问题答案: 我与KeyCloak和CORS以及所有这些都进行了大约两个星期的斗争,这是我的解决方案(针对keycloak 3.2.1): 这全部与配置KeyCloa
问题内容: 我陷入了API网关问题,并且在AWS论坛上浏览了所有其他SO解答,并通过了他们的文档,但仍然不满意。 我正在尝试使用AWS API网关设置API,该API调用Lambda函数,该函数读取/写入DynamoDB中的表。 DynamoDB的Lambda函数正在运行。我已经在AWS中创建了一个API,并为其创建了GET和OPTIONS方法。我读到AWS并没有仅对GET / POST强制执行O
我目前正在转换一个项目从。NET框架进入。网5. 当我到达新系统中的一个endpoint时。NET5项目我得到以下异常。 系统InvalidOperationException:'误用的标头名称,'访问控制允许源'。确保请求头与HttpRequestMessage一起使用,响应头与HttpResponseMessage一起使用,内容头与HttpContent对象一起使用。” endpoint看起来
Response.AddHeader(“Access-Control-Allow-Origin”,“*”)是如何实现的;行设置多个标题时,包括,但没有当我删除它?
问题内容: 我正在使用Ajax使用其API从Twitter获取数据。我正在尝试使用jsonp,从我所能看到和理解的角度来看,我认为我所做的一切都正确(显然不是)。 上面的代码在Chrome和Firefox中均生成错误 XMLHttpRequest无法加载 http://twitter.com/status/user_timeline/padraicb.json?count=10&callback=
我有一个码头服务器来运行我的Web服务。最近我开发了一个程序来使用Web服务,并遇到了Access-Control-Allow-Origin问题。 如何将访问控制Allow Origin:*添加到jetty嵌入式服务器。 下面是webappcontext代码。 非常感谢。