简体   繁体   English

访问控制允许起源不适用于POST请求中的Ajax

[英]Access-control-allow-origin not working with ajax in a POST request

I have a problem with the header "Access-control-allow-origin", I use next code to make a request: 我的标头“ Access-control-allow-origin”有问题,我使用下一个代码提出请求:

<script type='text/javascript'>
function save() {
           $.ajax(
         {
        type: 'POST',
        url: "...",                
        contentType: 'application/json',
        data: '{"cuspp":"228061JGLIR5", "userWeb":"46689"}',
        success: function (data) {
                console.log("It Works");
                console.log (data);
                if (data.codigo==0){
                    console.log(data.mensaje);
                }else{
                    console.log(data.mensaje);

                }
             },
        error: function (jqXHR, textStatus, errorThrown) {
                    console.log("error");
             }
         });
}
</script>

And the response it's made by a java client: 响应是由Java客户端做出的:

@POST
@Path("/pcnct020")
@ApiOperation(value = "Save events.", notes = "PCNCT020", responseClass = 
"data.Answer")
public Response saveEvents(
    @ApiParam(value="Structure of Event", required = false) Evento event) {     


    Answer<Result> answer = Validator.validate(event);

    if (answer.esOK()) {

        int size = event.textDetail.length();

        int count = size / 60;

        String comment =  event.textDetail;
        int secuence = 0;

        for (int j = 0; j <= count; j++) {
            evento.secuence = secuence;
            String newString;

            if (j == 0) {                                           
                if (size < 60) {                                    
                    newString = comment.substring(j * 60);

                } else {                                            
                    newString = comment.substring(j * 60,
                            (j * 60) + 60);
                }

            } else if (j == count) {                            
                newString = comment.substring(j * 60);          
                if (newString.equals("")) {                     
                    break;
                }

            } else {
                newString = comment.substring(j * 60,
                        (j * 60) + 60);
                if (newString.equals("")) {
                    break;
                }
            }
            event.textDetail = newString;   
            answer.setAnswer(event.saveEvent());
            secuence = Integer.parseInt(answer.ans.status);
        }

    }
    return Response
             .status(200)
             .header("Access-Control-Allow-Origin", "...")
             //.header("Access-Control-Allow-Credentials", "true")
             //.header("Access-Control-Allow-Headers", "Origin")
             //.header("Access-Control-Allow-Methods", "GET, POST, DELETE, 
                PUT, PATCH, HEAD, OPTIONS")
             //.header("Conten-Type","application/application/json")
             .entity(answer)
             .build();

}

When trying to access from the address indicated the header "Access-Control-Allow-Origin", in the browser console I get this error: 当尝试从指示的地址访问标题“ Access-Control-Allow-Origin”时,在浏览器控制台中出现此错误:

XMLHttpRequest cannot load http://sdpeapp00024.pe.intranet:9080/ccws/rest/ops/pcnct020 . XMLHttpRequest无法加载http://sdpeapp00024.pe.intranet:9080 / ccws / rest / ops / pcnct020 Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. 对预检请求的响应未通过访问控制检查:请求的资源上不存在“ Access-Control-Allow-Origin”标头。 Origin ' http://i6.sura.pe ' is therefore not allowed access. 因此,不允许访问源“ http://i6.sura.pe ”。

I do not know what else I could do. 我不知道我还能做什么。 I've tried adding other headers, like the comments in the response from java code and I always get the same error. 我尝试添加其他标头,例如来自Java代码的响应中的注释,但我总是遇到相同的错误。

I would greatly appreciate your help. 非常感谢您的帮助。

UPDATE: 更新:

  public void getService(){

        try {

         String urlWS = "Web Service Url";

         String url = urlWS;

         CloseableHttpClient httpclient = HttpClients.createDefault();

         HttpPost httpPost = new HttpPost(url);

         httpPost.setHeader("Content-type", "application/json");

         StringEntity params =new StringEntity("
         {\"cuspp\":\"228061JGLIR0\", \"usuarioWeb\":\"46683\");                                        


         httpPost.setEntity(params);


         CloseableHttpResponse response = 
         httpclient.execute(httpPost);

         System.out.println(response.getStatusLine());               

         System.out.println(response.getStatusLine().getStatusCode());

         if(response.getStatusLine().getStatusCode() == 200){
             BufferedReader brResponse = new BufferedReader(new 
             InputStreamReader(response.getEntity().getContent()));
             String responseText = "";
             String output = "";
             while ((output = brResponse.readLine()) != null) {
                        responseText += output;
             }
             System.out.println(responseText);


        }             

    } catch (Exception excepcion) {            
            System.out.println(excepcion.toString());
    }
    finally{

    }
}  

I made a client with java and works fine. 我用Java制作了一个客户端,并且工作正常。 I don´t really know why using Ajax doesn´t works, but this shows that the web service works correctly and the problem is in the client. 我真的不知道为什么使用Ajax无效,但是这表明Web服务可以正常工作,而问题出在客户端上。

Greetings. 问候。

PS. PS。 In the code I do not put the urls because I am not allowed to publish with more than two urls, but they are the same ones that are displayed in the error message. 在代码中,我不放置网址,因为不允许发布两个以上的网址,但它们与错误消息中显示的网址相同。

The Solution that I found was create a new class that implements ContainerResponseFilter interface (com.sun.jersey.spi.container) using the next code: 我找到的解决方案是创建一个新类,该类使用以下代码实现ContainerResponseFilter接口(com.sun.jersey.spi.container):

@Provider
public class SummerResponseFilter implements ContainerResponseFilter {

@Override
public ContainerResponse filter(ContainerRequest request, ContainerResponse response) 
{

    //INICIO OT 10533 - PSC001
    String ruta = request.getPath();

    if(ruta.contains("pcnct020")){
        response.getHttpHeaders().add("Access-Control-Allow-Origin", "*");
        response.getHttpHeaders().add("Access-Control-Allow-Methods","GET, OPTIONS, 
        HEAD, PUT, POST");
        response.getHttpHeaders().add("Access-Control-Allow-Headers","Content-Type");

    }

    //FIN OT 10533 - PSC001

    if (Logger.isDebugEnabled()) {
        Logger.debug("Finaliza el proceso de la url [%s] %s", request.getMethod(), 
       request.getRequestUri().toString());
    }
    if (Logger.isTraceEnabled()) {
        Logger.trace("Response - Headers    = [ %s ]",           
        response.getHttpHeaders().toString());
        Logger.trace("Response - Status     = [ %d ]", response.getStatus());
    }
    Answer.clean();
    return response;
 }

} }

And then define in xml at this way: 然后以这种方式在xml中定义:

 <init-param>
      <param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
      <param-value>filter.SummerResponseFilter</param-value>
 </init-param>

With this solution I can resolve my problem. 使用此解决方案,我可以解决我的问题。 I Hope can help anyone with the same problem. 我希望可以帮助遇到相同问题的任何人。

Thank you for your answers. 谢谢您的回答。

This link should give you a basic idea of CORS. 链接应为您提供CORS的基本概念。

In short a CORS error occurs when your client on domain www.example1.com* tries to hit an api which is hosted on www.example2.com . 简而言之,当您在域www.example1.com *上的客户端尝试访问托管在www.example2.com上的api时,就会发生CORS错误。 The CORS error you get is a security flag by the browser. 您收到的CORS错误是浏览器的安全标志。

So you can solve it in 2 ways. 因此,您可以通过2种方式解决它。

  1. On your backend server www.example2.com . 在您的后端服务器www.example2.com上 Enable CORS headers for all incoming requests(Allow requests with headers from other origins). 为所有传入请求启用CORS标头(允许带有其他来源标头的请求)。 and in your AJAX request set CORS headers. 并在您的AJAX请求中设置CORS标头。 Hence request goes from Client -> www.example2.com/post_url 因此,请求来自客户端-> www.example2.com/post_url

  2. I prefer this method. 我更喜欢这种方法。 From your client which is on www.example1.com hit an internal route www.example1.com/api/post_url and forward all requests to /api to www.example2.com via nginx or apache server config. 从位于www.example1.com的客户端中,打一条内部路由www.example1.com/api/post_url,然后将所有请求通过nginx或apache服务器配置转发到/apiwww.example2.com Hence request goes from Client -> www.example1.com/api/post_url -> www.example2.com/post_url 因此,请求来自客户端-> www.example1.com/api/post_url-> www.example2.com/post_url

Implement ContainerResponseFilter in your service. 在您的服务中实现ContainerResponseFilter。 This should fix your problem, 这应该可以解决您的问题,

public class Filter implements ContainerResponseFilter {

    @Override
    public ContainerResponse filter(ContainerRequest request,
            ContainerResponse response) {

        response.getHttpHeaders().add("Access-Control-Allow-Origin", "*");
        response.getHttpHeaders().add("Access-Control-Allow-Headers",
                "origin, content-type, accept, authorization, X-Request-With");
        response.getHttpHeaders().add("Access-Control-Allow-Credentials",
                "true");
        response.getHttpHeaders().add("Access-Control-Allow-Methods",
                "GET, POST, PUT, DELETE, HEAD");

        return response;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM