Angular5发送POST请求失败但Postman可用,跨域问题求助
解决Angular5 + Wildfly8 Java后端的CORS跨域问题
兄弟,你这遇到的是典型的CORS跨域资源共享问题——浏览器出于安全限制,当前端(http://localhost:4200)和后端(http://localhost:8080)不在同一个源时,发送带application/json这类自定义Content-Type的POST请求前,会自动发起一个OPTIONS预检请求,检查后端是否允许该跨域操作。现在你的Wildfly后端没处理这个预检请求,也没返回必要的CORS响应头,所以浏览器直接拦截了请求。
下面给你几个实用的解决方案,按需选择:
方案一:Wildfly全局配置CORS过滤器(无需改代码)
这种方式对所有部署在Wildfly上的应用生效,适合快速解决问题:
- 找到Wildfly安装目录下的
standalone/configuration/standalone.xml(域模式用domain.xml) - 在
<subsystem xmlns="urn:jboss:domain:undertow:2.0">(版本号可能略有不同)下的<server>→<host>标签内,添加过滤器配置:
<filters> <response-header name="Access-Control-Allow-Origin" header-value="http://localhost:4200"/> <response-header name="Access-Control-Allow-Methods" header-value="GET, POST, PUT, DELETE, OPTIONS"/> <response-header name="Access-Control-Allow-Headers" header-value="Content-Type, Authorization"/> <response-header name="Access-Control-Allow-Credentials" header-value="true"/> </filters>
- 接着在同一
<host>标签下的<location>节点后,添加过滤器引用:
<filter-ref name="Access-Control-Allow-Origin"/> <filter-ref name="Access-Control-Allow-Methods"/> <filter-ref name="Access-Control-Allow-Headers"/> <filter-ref name="Access-Control-Allow-Credentials"/>
- 重启Wildfly服务器即可生效。
方案二:Java后端添加自定义CORS过滤器(仅当前应用生效)
如果只想给当前Java应用配置CORS,写一个Servlet过滤器就行:
- 创建过滤器类:
import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebFilter("/*") // 拦截所有请求路径 public class CorsFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException {} @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletResponse httpResponse = (HttpServletResponse) response; // 设置允许跨域的源 httpResponse.setHeader("Access-Control-Allow-Origin", "http://localhost:4200"); // 允许的请求方法 httpResponse.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); // 允许的请求头 httpResponse.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization"); // 是否允许携带Cookie httpResponse.setHeader("Access-Control-Allow-Credentials", "true"); // 直接处理OPTIONS预检请求,返回200状态码 if ("OPTIONS".equalsIgnoreCase(((javax.servlet.http.HttpServletRequest) request).getMethod())) { httpResponse.setStatus(HttpServletResponse.SC_OK); return; } chain.doFilter(request, response); } @Override public void destroy() {} }
- 如果项目没启用Servlet 3.0注解支持,就在
web.xml里手动注册过滤器:
<filter> <filter-name>CorsFilter</filter-name> <filter-class>com.your.package.CorsFilter</filter-class> </filter> <filter-mapping> <filter-name>CorsFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
- 重新部署应用到Wildfly即可。
方案三:JAX-RS接口用注解配置(灵活控制)
如果你的后端接口是用JAX-RS(Wildfly自带RESTEasy实现)写的,直接用@CrossOrigin注解更灵活:
import javax.ws.rs.CrossOrigin; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Consumes; import javax.ws.rs.Produces; import javax.ws.rs.core.Response; @Path("/v1/events") // 给整个资源类配置CORS @CrossOrigin(origins = "http://localhost:4200", methods = {POST, GET, PUT, DELETE}, allowedHeaders = {"Content-Type", "Authorization"}) public class EventResource { @POST @Path("/addevent") @Consumes("application/json") @Produces("application/json") public Response addEvent(Event event) { // 你的业务逻辑代码 return Response.ok().build(); } }
注意事项
生产环境部署时,记得把Access-Control-Allow-Origin的值改成前端实际的域名,不要用*(如果需要携带Cookie,*不支持Credentials)。
内容的提问来源于stack exchange,提问作者rahs
相关产品推荐
相关产品推荐

