2015-09-25 66 views
2

我有一個奇怪的問題,涉及:CORS,XMLHttpRequest和JAX-RS。 我們想從mysite.comJAX-RS - CORS只適用於application/xml,不適用於應用程序/ json

當我們用頭這個請求失敗,從AJAX調用我們的REST的API(Java中,JAX-RS)在service.myapi.comAccept: 'application/json'

$.ajax({ 
    type: 'POST', 
    url: 'https://service.myapi.com/rest/machine/metadata', 
    headers: { 
     'Accept': 'application/json', 
     'Content-Type': 'application/json', 
     'Session-Token': myToken 
    }, 
    data: JSON.stringify({ 
     'machine-number': 1 
    }) 
}); 

獲取來自瀏覽器的以下信息:

跨來源請求阻止:同源策略不允許讀取遠程RESO urce在​​。 (原因:缺少CORS頭'Access-Control-Allow-Origin')。

但是,如果我更改爲Accept: 'application/xml'它按預期方式工作(!)

這是我的樣子,增加了CORS頭

private static final String ALLOW_HEADERS = createAllowHeaders(); 

    @Override 
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { 

    HttpServletRequest request = (HttpServletRequest) req; 
    HttpServletResponse response = (HttpServletResponse) res; 

    try { 
     chain.doFilter(request, response); 
    } catch(Exception e) { 
     response.setStatus(500); 
    } finally { 
     response.addHeader("Access-Control-Allow-Origin", "*"); 
     response.addHeader("Access-Control-Expose-Headers","Session-Token"); 
     response.addHeader("Access-Control-Allow-Headers", ALLOW_HEADERS); 
     response.addHeader("Access-Control-Allow-Credentials", "true"); 
     response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD"); 
    } 
    } 

    private static String createAllowHeaders() { 
    return new StringJoiner(", ") 
      .add("Access-Control-Allow-Headers") 
      .add("X-Requested-With") 
      .add("Access-Control-Request-Method") 
      .add("Access-Control-Request-Headers") 
      .add("origin") 
      .add("content-type") 
      .add("accept") 
      .add("authorization") 
      .add("Session-Token") 
      .toString(); 
    } 

與JAX-RS註解的方法來處理請求的服務器

過濾器上

@Path("/metadata") 
@POST 
@Consumes({ APPLICATION_XML, APPLICATION_JSON }) 
@Produces({ APPLICATION_XML, APPLICATION_JSON }) 
public Response getMetadata(@Context HttpServletRequest req, MetadataRequest m) { 
    //... 
} 

我不知道wh y使用Accept: 'application/json'時不起作用。經過Chrome和Firefox測試。在兩個瀏覽器中獲得相同的結果。

回答

1

這是每個規格的預期行爲。如果Content-type的值爲application/json,則不是what CORS defines as a simple header,因此觸發CORS preflight request

參見請求的不安全請求標誌被設置並且在...請求的首部列表中的標頭是不是一個簡單包頭情況下的the Main fetch algorithm in the spec步驟8。

唯一不會觸發CORS預檢請求的Content-type值爲text/plain,multipart/form-data,application/x-www-form-urlencoded