Access-control-allow-origin 不能在 POST 请求中使用 ajax

Posted

技术标签:

【中文标题】Access-control-allow-origin 不能在 POST 请求中使用 ajax【英文标题】:Access-control-allow-origin not working with ajax in a POST request 【发布时间】:2018-02-09 18:24:54 【问题描述】:

我的标题“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>

以及它是由 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();


当尝试从标头“Access-Control-Allow-Origin”指示的地址访问时,在浏览器控制台中出现此错误:

XMLHttpRequest 无法加载 http://sdpeapp00024.pe.intranet:9080/ccws/rest/ops/pcnct020。对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。 Origin 'http://i6.sura.pe' 因此不允许访问。

我不知道我还能做什么。我尝试添加其他标头,例如来自 java 代码的响应中的 cmets,但我总是得到相同的错误。

非常感谢您的帮助。

更新:

  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

    
  

我用java做了一个客户端并且工作正常。我真的不知道为什么使用 Ajax 不起作用,但这表明 Web 服务工作正常并且问题出在客户端。

您好。

PS。在代码中我没有放置 url,因为我不允许发布超过两个 url,但它们与错误消息中显示的相同。

【问题讨论】:

看来您需要为端点启用 CORS 检查此spring.io/guides/gs/rest-service-cors 谢谢,但我没有使用 Spring Framework。 【参考方案1】:

我找到的解决方案是使用以下代码创建一个实现 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;
 

然后在xml中这样定义:

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

有了这个解决方案,我可以解决我的问题。我希望可以帮助任何有同样问题的人。

感谢您的回答。

【讨论】:

【参考方案2】:

这个link 应该让你对 CORS 有一个基本的了解。

简而言之,当您在域 www.example1.com* 上的客户端尝试访问托管在 www.example2.com 上的 api 时,就会发生 CORS 错误。您收到的 CORS 错误是浏览器的安全标志。

所以你可以通过两种方式解决它。

    在您的后端服务器 www.example2.com 上。为所有传入请求启用 CORS 标头(允许带有来自其他来源的标头的请求)。并在您的 AJAX 请求中设置 CORS 标头。因此请求来自客户端 -> www.example2.com/post_url

    我更喜欢这种方法。从您在 www.example1.com 上的客户端点击内部路由 www.example1.com/api/post_url 并将所有请求转发到 /api www.example2.com 通过 nginx 或 apache 服务器配置。因此请求来自客户端 -> www.example1.com/api/post_url -> www.example2.com/post_url

【讨论】:

感谢您的回复。我尝试了第一个解决方案,但没有成功。根据我的阅读,该错误是通用的,并不一定表明真正的问题。关于第二种方案,我不能使用其他服务器,项目是在Websphere Server中实现的。【参考方案3】:

在您的服务中实现 ContainerResponseFilter。这应该可以解决您的问题,

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;
    

【讨论】:

以上是关于Access-control-allow-origin 不能在 POST 请求中使用 ajax的主要内容,如果未能解决你的问题,请参考以下文章

PHP没有按顺序执行

跨域请求被阻止 Symfony/AngularJS

C# MVC js 跨域

PHP Ajax 跨域问题最佳解决方案

PHP Ajax 跨域问题最佳解决方案

PHP Ajax 跨域问题最佳解决方案