代码之家  ›  专栏  ›  技术社区  ›  bvdb

邮政交叉来源

  •  0
  • bvdb  · 技术社区  · 7 年前

    我有一个Jetty http服务器和一些Jersey rest服务。这些服务是从运行在节点服务器上的React网站调用的。

    由于这种设置的跨源性,我不得不添加一些HTTP头。基本上,我所有的web服务都返回一个 createOkResult()

    @POST
    @Path("orders/quickfilter")
    @Consumes(MediaType.APPLICATION_JSON)
    public Response getQuickFilterProductionOrders(String data) 
    {
      ...
      return createOkResult(json.toString());
    }
    
    protected Response createOkResult(Object result)
    {
      return buildCrossOrigin(Response.ok().entity(result));
    }
    
    protected static Response buildCrossOrigin(Response.ResponseBuilder responseBuilder)
    {
      return responseBuilder.header("Access-Control-Allow-Origin", "*")
              .header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT")
              .allow("OPTIONS")
              .build();
    }
    

    对于 @GET 运行良好的Web服务。但是当我创建一个 @POST

    WebBrowser(chrome和firefox)返回以下类型的错误:

    '访问XMLHttpRequest' http://localhost:59187/rs/production/orders/quickfilter http://localhost:3000 '已被CORS策略阻止:请求的资源上不存在'Access Control Allow Origin'标头。

    所以,乍一看,我会觉得头文件还是不见了。问题是,当我用Postman之类的工具测试这个服务时,所有的头文件都已经准备好了,服务甚至返回了请求的数据。

    postman screenshot

    这是发帖请求的截图。

    在我的前端(在节点服务器上运行),我使用axios API,它使用promises,我的请求如下所示:

    const url = "http://localhost:59187/rs/production/orders/quickfilter";
    const data = JSON.stringify(request);
    const headers = { headers: { "Content-Type": "application/json" } };
    const promise = axios.post(url, data, headers);
    

    现在我有一个HTTP错误500,如果我删除内容类型头,我会得到一个不受支持的媒体异常。所以,我有理由相信内容类型是可以的。

    1 回复  |  直到 7 年前
        1
  •  0
  •   bvdb    7 年前

    保罗·桑索塔给我指出了正确的方向。 最后我给系统添加了一个过滤器 ServletContextHandler . 与链接的文章不同,我实际上不必从头创建过滤器。我可以使用一个现有的过滤器类:即。 org.eclipse.jetty.servlets.CrossOriginFilter .

    FilterHolder filterHolder = context.addFilter(CrossOriginFilter.class, "/*", EnumSet.allOf(DispatcherType.class));
    filterHolder.setInitParameter(CrossOriginFilter.ALLOWED_METHODS_PARAM, "GET,PUT,POST,DELETE,OPTIONS");
    filterHolder.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "*");
    filterHolder.setInitParameter(CrossOriginFilter.ALLOWED_HEADERS_PARAM, "Content-Type,Authorization,X-Requested-With,Content-Length,Accept,Origin");
    filterHolder.setInitParameter(CrossOriginFilter.ALLOW_CREDENTIALS_PARAM, "true");
    filterHolder.setInitParameter(CrossOriginFilter.CHAIN_PREFLIGHT_PARAM, "false");
    

    上面的一些参数可以省略,因为它们是默认值。但对我来说最关键的是 CHAIN_PREFLIGHT_PARAM false .

    一个很好的副作用是,我可以简化实际服务的代码。它们不再需要添加特殊的头,相反,它们现在只需返回 Response.ok().entity(result).build(); .

    推荐文章