如何在 Maven 中为跨域 POST 请求激活 CORS 过滤器?

Posted

技术标签:

【中文标题】如何在 Maven 中为跨域 POST 请求激活 CORS 过滤器?【英文标题】:How do I activate a CORS Filter for Cross Domain POST Requests in Maven? 【发布时间】:2018-01-07 16:06:15 【问题描述】:

我将一个 React 应用程序部署到一个单独的 Google App Engine,它发送一个 POST 请求以从 Web 应用程序中获取一些数据,并且我正在尝试解析我的 React 应用程序中的数据。我能够从 PostMan 获取正确的数据,但相同的请求不断给我一个“请求的资源上不存在‘Access-Control-Allow-Origin’标头”错误。 我目前正在接收来自 Bigger Webapp 的 PostRequest,如下所示:

@POST
@Path("/initializer")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public String getOrCreateSeller(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException 

    this.shopifyStoreName = body.get("id").toString();
    long hashedName = hashStoreName();
    SellerId sellerId = new SellerId(hashedName);
    try 
        Seller seller = sellerService.findSellerById(sellerId);
        getStore(seller);
        String json = getResponseJson();
        return Response.ok(json, MediaType.APPLICATION_JSON).build();
     catch (NotFoundException e) 
        Seller seller = new Seller(sellerId.toDatastoreId(), 
     this.shopifyStoreName, 3L);
        datastoreRepository.transact(() -> 
            sellerValidator.validate(seller);
            sellerRepository.save(seller);
        );
        createStore(seller);
        String json = getResponseJson();
        Response.ResponseBuilder r = Response.ok(json, MediaType.APPLICATION_JSON);
        return r.build();
    

事实证明,在更大的 web 应用程序中,我从中获取数据包含一个“CORSFilter”类,如下所示:

public class CORSFilter implements Filter 

@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException,
        ServletException 
    HttpServletResponse httpResp = (HttpServletResponse) resp;
    HttpServletRequest httpReq = (HttpServletRequest) req;

    httpResp.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, OPTIONS");
    httpResp.setHeader("Access-Control-Allow-Origin", "*");
    if (httpReq.getMethod().equalsIgnoreCase("OPTIONS")) 
        httpResp.setHeader("Access-Control-Allow-Headers",
                httpReq.getHeader("Access-Control-Request-Headers"));
    
    chain.doFilter(req, resp);


@Override
public void init(FilterConfig arg0) throws ServletException 


@Override
public void destroy() 

因此,我觉得我应该使用这个类来启用 COR,但我不确定如何。请帮忙!

【问题讨论】:

【参考方案1】:

由于您的服务器端代码似乎正在使用 JAX-RS,一种将 CORS 标头添加到 JAX-RS 应用程序的方法(遵循与您的 CORSFilter 相同的规则)是只是将此类添加到您的应用中:

@Provider
@Priority(Priorities.HEADER_DECORATOR)
public class AccessControlResponseFilter implements ContainerResponseFilter 
    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException 
        final MultivaluedMap<String,Object> headers = responseContext.getHeaders();

        headers.add("Access-Control-Allow-Methods", "GET, POST, PUT, OPTIONS");
        headers.add("Access-Control-Allow-Origin", "*");
        if (requestContext.getMethod().equalsIgnoreCase("OPTIONS")) 
            headers.add("Access-Control-Allow-Headers", requestContext.getHeaderString("Access-Control-Request-Headers"));
        
    


或者,如果您的项目可以使用 CORSFilter 类,您可以将其作为 servlet 过滤器添加到您的 web.xml:

<filter>
    <filter-name>CORSFilter</filter-name>
    <filter-class>com.mycompany.CORSFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>CORSFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

从两个解决方案中选择一个,而不是两个。

【讨论】:

要使用第二种解决方案,我必须扩展我提供的 CORSFilter,对吧? 并非如此。 CORSFilter 必须存在于您要将其添加到其 web.xml 的应用程序中。 我的集线器中似乎有 5 个以上的 web.xml,其中一些实际上确实包含了 CORSFilter 映射,但我仍然遇到同样的错误。然后,我尝试将您向我展示的第一堂课添加到我的中心,但这并没有什么不同。但是,我可以通过在禁用网络安全的浏览器中启动所有内容来绕过该错误。 您必须将其添加到 .war 文件的 web.xml 中,该文件包含方法为 getOrCreateSeller() 的类【参考方案2】:

您可以在控制器类中使用@CrossOrigin 注解。可以获取更多信息here - crossorigin

【讨论】:

以上是关于如何在 Maven 中为跨域 POST 请求激活 CORS 过滤器?的主要内容,如果未能解决你的问题,请参考以下文章

为跨源请求设置 cookie

vue 如何实现跨域

跨域 WebAPI 批量请求

jsonp

php分享二十五:跨域请求

vue-resource可以跨域直接发送POST请求吗?