跨域 put 调用不适用于 Access-Control-Allow-Origin

Cross domain put call does not work with Access-Control-Allow-Origin

我面临与跨域 PUT 调用相关的问题,我已允许从服务器端 Access-Control-Allow-Origin 放置它不起作用。

    @PUT
    @Path("/getresponse/{caller}")
    @Produces({MediaType.APPLICATION_JSON})
    public Response getResponseData(@PathParam("caller") String caller ,@QueryParam("ticket")String ticket ,@FormParam("formParam") String data){


        ResponseBuilder resp;
        System.out.println("name of caller is -> "+ caller);
        System.out.println("query param ticket -> "+ ticket);
        System.out.println("form param data->" + data);
        Employee emp = new Employee();
        emp.setAge(23);
        emp.setName("data");
        Gson gson = new Gson();
        String responseJson =  gson.toJson(emp);
        resp=Response.ok(responseJson);//header("Access-Control-Allow-Origin", "*")
        resp.header("Access-Control-Allow-Origin", "*")
        .header("Access-Control-Allow-Methods", "GET, POST, PUT, OPTIONS");

         return resp.build();
    }

每当我从 jquery ajax 方法调用它时,它说 对预检请求的响应未通过访问控制检查:请求的资源上不存在 'Access-Control-Allow-Origin' header

我有上述服务的相同副本,但带有 POST 签名,当我调用该服务时它调用服务没有任何问题 Post服务代码是

    @POST
    @Path("/getresponses/{caller}")
    @Produces({MediaType.APPLICATION_JSON})
    public Response getResponseData1(@PathParam("caller") String caller ,@QueryParam("ticket")String ticket ,@FormParam("formParam") String data){


        ResponseBuilder resp;
        System.out.println("name of caller is -> "+ caller);
        System.out.println("query param ticket -> "+ ticket);
        System.out.println("form param data->" + data);
        Employee emp = new Employee();
        emp.setAge(23);
        emp.setName("data");
        Gson gson = new Gson();
        String responseJson =  gson.toJson(emp);
        resp=Response.ok(responseJson);//header("Access-Control-Allow-Origin", "*")
        resp.header("Access-Control-Allow-Origin", "*")
        .header("Access-Control-Allow-Methods", "GET, POST");
        return resp.build();
    }

我的客户端代码是

$(document).ready(function(){
    // for post service
    $('#sendcall').on('click',function(e){
        var dataTosend ="formParam=data to send";
        $.ajax({
              url: 'http://someip:8099/Jqgrid/rest/getdata/getresponses/data?ticket=tick',
              contentType : 'application/x-www-form-urlencoded',
              data :dataTosend,   
              type: 'POST',
              success: function(data){
                alert(data);
              }
            });
    });

    //for PUT service
    $('#sendcall2').on('click',function(e){
        var datatosend ="formParam=data to send";
        $.ajax({
              url: 'http://someip:8099/Jqgrid/rest/getdata/getresponse/aliahsan?ticket=tick',
              contentType : 'application/x-www-form-urlencoded',
              data :datatosend,   
              type: 'PUT',
              crossDomain:true,
              beforeSend: function (xhr) {

                    console.log('header added');
                },
              success: function(data){
                alert(data);
              }
            });
    });
});

请帮助我解决为什么 PUT 无法处理这个问题。 任何帮助将不胜感激

不要在资源方法中添加所有 CORS headers,而是使用 Jersey 过滤器,如 in this post. The reason for this, is the CORS preflight request, which is defined in HTTP access control (CORS) 所述:

"preflighted" requests first send an HTTP request by the OPTIONS method to the resource on the other domain, in order to determine whether the actual request is safe to send.

因此该请求是一个 OPTIONS 请求,它期望返回 "Accept-Xxx" CORS headers 以确定服务器允许的内容。因此,将 headers 放在资源方法中没有任何影响,因为请求是使用 OPTIONS HTTP 方法发出的,您没有资源方法。这通常会导致向客户端发送 405 Method Not Allowed 错误。

当您在过滤器中添加 headers 时,每个请求都会通过此过滤器,甚至是 OPTIONS 请求,因此预检会根据 headers.

至于 PUT,也在上面的链接文档中描述(从上面的引用继续)

Cross-site requests are preflighted like this since they may have implications to user data. In particular, a request is preflighted if:

  • It uses methods other than GET, HEAD or POST. Also, if POST is used to send request data with a Content-Type other than application/x-www-form-urlencoded, multipart/form-data, or text/plain, e.g. if the POST request sends an XML payload to the server using application/xml or text/xml, then the request is preflighted.
  • It sets custom headers in the request (e.g. the request uses a header such as X-PINGOTHER)

这就是 POST 请求没有遇到相同问题的原因。