2015-03-25 50 views
1

我使用烬1.5使用grunt-cli,想发生Ajax调用使用dataType: "JSON" CORS支持。灰烬支持XDomainRequest(XDR)为CORS

Ember.$.ajax({ 
    type: "GET", 
    url: App.serverURL + 'logVisit', // callback for jsonP 
    data : { 
     'fp': App.fp 
    }, 
    dataType : "JSON", 
    success: function(response) { 
     console.log('DEBUG: visitor has been registered'); 
    }, 
    error: function(jqXHR, textStatus, errorThrown) { 
     console.log("DEBUG jqXHR.responseText : ",jqXHR.responseText); 
     var response = jqXHR.responseText; 

     console.log('Failure!'); 
     if(jqXHR.status&&jqXHR.status==400){ 
      // alert(jqXHR.responseText); 
      var response = $.parseJSON(jqXHR.responseText); 

      if (response) { 
       console.log(response.error); 
      } else { 
       // This would mean an invalid response from the server - maybe the site went down or whatever... 
       console.log("DEBUG: Inside jqXHR.status : Something went wrong"); 
      } 
     } else { 
      console.log("DEBUG: Something went wrong"); 
     } 
    } 
}); 

IE10/11其运行良好。但在IE8/9,因为它需要XDR对象,它没有工作和显示控制台

LOG: DEBUG jqXHR.responseText : undefined 
LOG: Failure! 
LOG: DEBUG: Something went wrong 

任何帮助或破解?

我的请求头:

Accept:application/json, text/javascript, */*; q=0.01 
Accept-Encoding:gzip, deflate, sdch 
Accept-Language:en-US,en;q=0.8 
Cache-Control:max-age=0 
Connection:keep-alive 
Host:localhost:8080 
Origin:http://localhost:9000 
Referer:http://localhost:9000/ 
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36 

在非IE浏览器的8/9响应头

Access-Control-Allow-Origin:* 
Content-Type:application/json 
Date:Wed, 25 Mar 2015 16:01:56 GMT 
Server:Apache-Coyote/1.1 
Transfer-Encoding:chunked 
+0

'jqXHR.responseText'的值是什么?也就是说,不是试图用'parseJSON'将它解析为json,而是将它回显给控制台('console.log(jqXHR.responseText);')。 – lsowen 2015-03-25 12:31:16

+0

在IE10/11上获得的响应是​​'undefined' – 2015-03-25 12:39:08

+0

“它运行良好,但由于XDR,它不能正常工作” - 这没有意义。它不能运行良好,不能同时正常工作。另外IE10/11不需要XDR,这是非常老版本的IE。 – Quentin 2015-03-25 12:58:37

回答

2

我发现我的答案以支持@ Isowen的回复。

我加入这一段代码window.App = Ember.Application.create({});之前支持XDRIE8/9

Ember.$.ajaxTransport(function(options, originalOptions, jqXHR) { 
    var xdr; 

    return { 
    send: function(_, completeCallback) { 
     xdr = new XDomainRequest(); 
     xdr.onload = function() { 
     if (xdr.contentType.match(/\/json/)) { 
      options.dataTypes.push("json"); 
     } 

     completeCallback(200, 'success', { text: xdr.responseText }); 
     }; 
     xdr.onerror = xdr.ontimeout = function() { 
     completeCallback(400, 'failed', { text: xdr.responseText }); 
     } 

     xdr.open(options.type, options.url); 
     xdr.send(options.data); 
    }, 
    abort: function() { 
     if(xdr) { 
     xdr.abort(); 
     } 
    } 
    }; 
}); 

,并按照@ Isowen的建议,一边做Ajax请求

Ember.$.ajax({ 
    type: "GET", 
    url: App.serverURL + 'logVisit', 
    data : { 
     'fp': App.fp 
    }, 
    dataType : "JSON", 
    xhrFields: {withCredentials: true}, // line added 
    .... 
}); 

人谁正在处理与REST适配器的请求可以使用

App.ApplicationAdapter = DS.RESTAdapter.extend({ 
    host: App.host, 
    namespace : App.namespace, 
    ajax: function(url, method, hash) { 
     hash = hash || {}; // hash may be undefined 
     hash.crossDomain = true; 
     hash.xhrFields = { // import line added 
      withCredentials: true // import line added  
     }; 
     console.log('DEBUG: inside RESTAdapter ajax call'); 
     return this._super(url, method, hash); 
    } 
}); 

,并在后端(这里春天 - Java的

@Component("corsFilter") 
public class CORSResponseFilter extends OncePerRequestFilter { 

    @Override 
    protected void doFilterInternal(HttpServletRequest request, 
            HttpServletResponse response, FilterChain filterChain) 
      throws ServletException, IOException { 

      response.addHeader("Access-Control-Allow-Origin", "http://YOUR-LINK"); // IMPORT LINE ADDED 
      response.addHeader("Access-Control-Allow-Credentials", "true"); // IMPORT LINE ADDED 
      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"); 
     } 
     filterChain.doFilter(request, response); 
    } 
} 

感谢@Isowen您的帮助。

0

看起来你缺少xhrFields.withCredentials字段设置为true(不是所有CORS请求都需要,只在IE10中部分支持)。

确保您的服务器正在返回Access-Control-Allow-Origin标头,并且该值与您的请求源相匹配。

服务器端CORS实施可能有问题。在针对httpbin.org运行的jsfiddle上对代码进行了轻微编辑的实现似乎可以在Firefox,Chrome和IE11中正常工作:http://jsfiddle.net/n94w774n/

编辑:

由于OriginHost都是本地主机(只是不同的端口),有两件事情你需要检查安全区域设置为本地主机:Access denied in IE 10 and 11 when ajax target is localhost

+0

该文档说'xhrFields.withCredentials'导致它发送cookie。我没有看到在旧版本的IE中使用XDR而不是XHR对象所做的事情。很明显,代码已经正确设置了“Access-Control-Allow-Origin”,否则它在现代浏览器中不起作用。 – Quentin 2015-03-25 12:57:10

+0

@Quentin:我已经提供了我的请求头。希望有帮助 – 2015-03-25 16:13:24

+0

@Isowen:我已经提供了我的回应标题。让我知道是否必须添加更多的参数。 – 2015-03-25 16:19:50