3

我在我的 Tomcat Java EE servlet 容器中运行了一个基于 REST 的 Web 服务。

我正在编写一个来自另一个域的 jquery 客户端,因此正在使用 CORS。它点击登录 Web 服务,然后是另一个调用。我最初使用 getJSON 实现了这两个调用并且调用工作正常,但是我没有让 JSESSIONID cookie 留在第二个调用上,因此 Web 服务有一个未经身份验证的会话并抛出错误。

在做研究之后,我遇到了做 ajax withCredentials 并认为这是我需要做的。AJAX 登录调用在预检中失败。

因此,当我嗅探到我的网络服务器的流量时,getJSON 调用作为两个 get 运行并且看起来很好,只是 cookie 没有随着第二个调用返回。当我运行 ajax 调用时,它会对我的服务器进行 OPTIONS 调用,在客户端上返回 200 状态,然后由于我似乎无法找到的原因在 jQuery 内部失败。

var jqxhr = jQuery.getJSON(loginUrl, {
  xhrFields: {
      withCredentials: true
  },
  crossDomain: true
})
.done(function(response) {
    AgileJurySessionKey = response;
    AgileJuryLoggedIn = true;
    doneCallback();
})
.fail(function() {
    failCallback();
});

这是同一调用的 AJAX 版本:

jQuery.ajax(loginUrl, {
    type: "GET",
    contentType: "application/json; charset=utf-8",
    success: function(data, status, xhr) {
        alert(data);
        doneCallback;
    },
    error: function(jqxhr, textStatus, errorThrown) {
        alert(errorThrown);
        failCallback;
    },
    xhrFields: {
        withCredentials: true
    },
    crossDomain: true
});

这两者有什么不同?

这是我为 CORS 放入 Web 服务器的过滤器:

/**
 * This filter allows access to our web services from clients that are not on the local domain
 * 
 * @author Xerox
 */
public class CorsFilter extends OncePerRequestFilter {

  /* (non-Javadoc)
   * @see org.springframework.web.filter.OncePerRequestFilter#doFilterInternal(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, javax.servlet.FilterChain)
   */
  @Override
  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
          throws ServletException, IOException {
      response.addHeader("Access-Control-Allow-Origin", "*");
      if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod())) {
          // CORS "pre-flight" request
          response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
          response.addHeader("Access-Control-Allow-Headers", "X-Requested-With,Origin,Content-Type,Accept,Set-Cookie");
          response.addHeader("Access-Control-Max-Age", "1800");//30 min
      }
      filterChain.doFilter(request, response);
  }
}
4

3 回答 3

4
jQuery.getJSON(loginUrl, {
  xhrFields: {
      withCredentials: true
  },
  crossDomain: true
})

的第二个参数$.getJSON是您要发送的数据,而不是选项对象。要使用这些,您需要$.ajax直接调用。

于 2013-07-17T16:33:08.543 回答
1

getJSON并不是一个真正的方法,它只是一个方便的函数,基本上是一个快捷方式:

$.ajax({
  dataType: "json",
});

所以基本上,$.getJSON() 的行为应该与 $.ajax() 相同,数据类型设置为“json”

于 2013-07-17T16:16:27.780 回答
0

由于 CORS 的持续问题,我最终放弃了这个棘手的问题,并从另一端解决了这个问题。

我使用返回的会话密钥来跟踪会话的长度,然后基于此重新附加安全性,这就是我最初设计安全性的方式。

于 2013-07-29T15:09:25.210 回答