首页 文章

AJAX CORS请求源被阻止 - Java Web服务

提问于
浏览
0

每次我们尝试通过AJAX JQuery访问我的REST Web服务时,我们都被Cross-Origin阻止了:

阻止跨源请求:同源策略禁止在http:// *****读取远程资源(原因:缺少CORS头“Access-Control-Allow-Origin”) .

我们在Glassfish 3.1.2上使用Java REST Web Service,使用Firefox Quantum 57的客户端 .

请看下面的代码:

$.ajax({
    type: 'POST',
    url: webservice + "/webresources/ivi/syncPassphrase",
    crossOrigin: true,
    data :JSON.stringify({
      'passPhrase' : passphrase
    }),
    dataType: 'json',
    async: false,
    contentType: 'application/json; charset=utf-8',
    crossDomain: true,
    success: function(data){ 
      syncData = data["output"];  
    }, error: function(){  

    }
});

我们已经从SO上的几个答案中读到了并且尝试过如下:

$.ajax({
    type: 'POST',
    url: webservice + "/webresources/ivi/syncPassphrase",
    crossOrigin: true,
    data :JSON.stringify({
      'passPhrase' : passphrase
    }),
    xhrFields: {
        withCredentials: true
    },
    dataType: 'json',
    async: true,
    contentType: 'application/json; charset=utf-8',
    crossDomain: true,
    timeout: 20000,
    beforeSend: function(xhr){ 
        xhr.setRequestHeader("Access-Control-Allow-Origin",'http://111.111.111.111:8080');
    },
    success: function(data){ 
      syncData = data["output"];  
      console.log("xxx1 " + syncData);
    }, error: function(xhr, status, error) {
      console.log("xxx2 " + xhr.responseText + " | " + status + " | " + error + " | ");
    }
});

但上面的代码仍会产生相同的错误 .

在服务器端,我们为每个请求设置允许交叉原点并像下面的代码一样响应:

@Override
public void filter(final ContainerRequestContext requestContext,
                  final ContainerResponseContext cres) throws IOException {
  cres.getHeaders().add("Access-Control-Allow-Origin", "*");
  cres.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
  cres.getHeaders().add("Access-Control-Allow-Credentials", "true");
  cres.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
  cres.getHeaders().add("Access-Control-Max-Age", "1209600");
}

我没想到了 . 任何的想法?

谢谢

1 回答

  • 0

    有几件事:

    • 您不需要在请求中发送ACAO标头 - 这一部分客户端代码不执行任何操作:
    beforeSend: function(xhr){
        xhr.setRequestHeader("Access-Control-Allow-Origin",'http://111.111.111.111:8080');
    },
    
    • Access-Control-Allow-Origin * (ACAO)响应标头与 Access-Control-Allow-Credentials: true (ACAC)标头不兼容 . 如果您需要cookie或身份验证,则必须指定 Access-Control-Allow-Origin: {value-of-Origin-request-header}

    第二个可以解决它 .

    UPDATE

    您的服务器代码应如下所示:

    @Override
    public void filter(final ContainerRequestContext requestContext,
                  final ContainerResponseContext cres) throws IOException {
      cres.getHeaders().add("Access-Control-Allow-Origin", "http://your-origin:port");
      cres.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
      cres.getHeaders().add("Access-Control-Allow-Credentials", "true");
      cres.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
      cres.getHeaders().add("Access-Control-Max-Age", "1209600");
    }
    

    但将 http://your-origin:port 替换为发出请求的页面域(包括端口,如果它知道您的服务器代码,但如果您可以检索Origin请求标头的值,而不是硬编码,那就更好了) .

    那更有意义吗?

相关问题