2013-04-18 2 views
0

여기 내 쿼리 (CORS 크로스 도메인 HTTP 요청을) 작동하지 않습니다 , 내가 할 때 성공 핸들러에서 :breezejs inlineCount는

var results = data.results; 
var recordCount = data.inlineCount; 

결과에 올바른 레코드가 들어 있습니다. 그러나 data.inlineCount는 null입니다.

어째서?

EDIT 모든 헤더를 반환하지 않습니다

getAllResponseHeaders을! X-InlineCount를 포함하여 대부분이 누락 된 것으로 나타났습니다.

크로스 도메인 HTTP 요청 (웹 사이트는 localhost에 있지만 내 webapi (웹 서비스)는 도메인의 서버에 있음)을 수행하고 있기 때문에 이것이라고 생각합니다. 이 문제를 어떻게 해결할 수 있습니까?

+0

한 지점에서 breeze는 jquery getResponseHeader 함수를 호출하고 X-InlineCount를 키 속성으로 전달합니다. 그러나 responseHeadersString은 매우 불완전하며이 속성을 포함하지 않으므로 응용 프로그램의 버그가 발생합니다. 문제는 Chrome의 응답 헤더에서 responseHeadersString에없는 많은 다른 속성과 함께 속성이 명확하게 여기에 있음을 알 수 있습니다. jquery의 버그입니까? 나는 최신 버전을 가지고있다. – Sam

답변

1

나는 동일한 문제가있었습니다. X-InlineCount 헤더가 노출되도록 서버를 구성해야합니다. 프로젝트 ASP .NET 웹 API를 사용하는 경우 당신은 당신의 Web.config에 다음 라인을 추가해야한다 또한

<system.webServer> 
    <httpProtocol> 
     <customHeaders> 
     <add name="Access-Control-Allow-Origin" value="*" /> 
     <add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" /> 
     <add name="Access-Control-Allow-Methods" value="GET,POST,OPTIONS" /> 
     <add name="Access-Control-Expose-Headers" value="X-InlineCount" /> 
     </customHeaders> 
    </httpProtocol> 

, 나는 파이어 폭스에 문제가 있었다, 그러나 파이어 폭스의 최신 버전에 문제가있다 해결되었습니다.

(요는 단지 예입니다, 모든 라인을 사용할 필요가 없습니다) 그것은 로그 이었기 때문에)

----- 편집 -----는

나는 잊고 있었던 전에. 브라우저는 CORS 호출을 수행 할 때 먼저 CORS 호출을 수행 할 수 있는지와 허용되는 항목이 있는지 확인하기 위해 옵션 호출을 보냅니다. 따라서이 OPTION 호출을 관리하려면 WEB API 프로젝트에 메시지 핸들러를 구현해야합니다. 구현은 다음입니다 : 당신이 당신의 Web.config에 있음을 넣으면

public class OptionsHttpMessageHandler : DelegatingHandler 
    { 
     protected override Task<HttpResponseMessage> SendAsync(
      HttpRequestMessage request, CancellationToken cancellationToken) 
     { 
      if (request.Method == HttpMethod.Options) 
      { 
       var apiExplorer = GlobalConfiguration.Configuration.Services.GetApiExplorer(); 


       var controllerRequested = request.GetRouteData().Values["controller"] as string; 
       var supportedMethods = apiExplorer.ApiDescriptions 
        .Where(d => 
        { 

         var controller = d.ActionDescriptor.ControllerDescriptor.ControllerName; 
         return string.Equals(
          controller, controllerRequested, StringComparison.OrdinalIgnoreCase); 
        }) 
        .Select(d => d.HttpMethod.Method) 
        .Distinct(); 

       if (!supportedMethods.Any()) 
        return Task.Factory.StartNew(
         () => request.CreateResponse(HttpStatusCode.NotFound)); 

       return Task.Factory.StartNew(() => 
       { 
        var resp = new HttpResponseMessage(HttpStatusCode.OK); 
        resp.Headers.Add("Access-Control-Allow-Origin", "*"); 
        resp.Headers.Add("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, Accept, Security,Token-Access"); 
        resp.Headers.Add("Access-Control-Allow-Methods", "GET,POST,OPTIONS"); 
        resp.Headers.Add("Access-Control-Expose-Headers", "X-InlineCount"); 

        return resp; 
       }); 
      } 

      return base.SendAsync(request, cancellationToken); 
     } 
    } 

당신은 다음 섹션을 생략 할 수 있습니다.

resp.Headers.Add("Access-Control-Allow-Origin", "*"); 
resp.Headers.Add("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, Accept, Security,Token-Access"); 
resp.Headers.Add("Access-Control-Allow-Methods", "GET,POST,OPTIONS"); 
resp.Headers.Add("Access-Control-Expose-Headers", "X-InlineCount"); 

귀하의 문제를 해결하는 데 도움이되기를 바랍니다.

PD : 영어로 죄송합니다. 제 첫 번째 언어가 아닙니다.

+0

정말 고마워요. 내일 아침에해볼 게요. 효과가 있다면 알려 드리겠습니다. – Sam

+0

그게 나를 위해 작동하지 않았다. 네가 한 짓이 있니? – Sam

+0

이 솔루션은 저에게 효과적이었습니다. 문제를 일으킬 수 있다고 생각되는 유일한 두 가지 사항은 다음과 같습니다. 1. web.config의 줄을 올바른 위치에 두었습니까? 2. 어떤 브라우저를 사용하고 있습니까? 마지막 버전을 사용해야합니다. 이 솔루션은 Chrome의 마지막 버전에서 저에게 효과적이었습니다. 다음 링크에서 자세한 정보를 찾을 수 있습니다. https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS – jvrdelafuente

3

우리는이 문제를 확인했습니다. 우리는 inlineCount을 헤더 밖으로 옮겨서 결과 페이로드으로 옮길 것입니다. 그 위치는 아마도 처음에 있어야했을 것입니다. 그 회사 날짜는 없지만 곧.

업데이트 : 4/18/2013. 우리는이 픽스를 내부적으로 구현했으며 테스트를 통과했습니다. 우리는 다음 NuGet (1.3.0 이후의 것)에 배포 할 것입니다. 이 문제가 다시 발생하면이 답변을 다시 업데이트하겠습니다.

누구나 할 수있는대로 this jsFiddle을 수정하여 문제를 재현했습니다.

바이올린은 Breeze 서버에 Todos를 노출하는 요청을 만듭니다. 당연히 Breeze 서버는 jsFiddle과 다른 도메인에 있으므로 CORS가 쿼리 및 저장 작업을 수행해야합니다. - 내가의 Web.config 변화 당신이 실제로 일을 권장하는 것이 놀랍군요

 
function getAllTodos() { 
    var query = breeze.EntityQuery.from("Todos") 

    // added for Cross-Origin inlineCount header testing 
    .orderBy('Description') 
    .skip(1).take(3) 
    .inlineCount(true); 

    log("Getting Todos"); 
    return manager.executeQuery(query) 
    .then(querySucceeded).fail(failed); 

    function querySucceeded(data) { 
     var count = data.results.length; 
     log("Retrieved " + count); 

     // added for Cross-Origin inlineCount header testing 
     log("Inline count: "+ data.inlineCount); 
     log("Headers: " + data.XHR.getAllResponseHeaders()); 

     if (!count) { 
      log("No Todos"); return; 
     } 
     viewModel.items(data.results); 
    } 
} 

@jvrdelafuente :

나는 다음에 getAllTodos 방법을 변경했습니다. 나는 Web.config에 대한 그런 변경이 브라우저가하는 것이 아니라 서버가하는 일에만 영향을 줄 것이라고 생각했을 것입니다.

네트워크 트래픽을 조사 할 때 서버가 "X-InlineCount"헤더 ()를 제안 변경 (예 :)과 함께 보내고 있음을 알 수 있습니다. 브라우저 (IE10 및 Chrome 이상)는 일반적인 breeze 앱에서 AJAX 통신을 담당하는 jQuery.AJAX의 헤더를 숨기고있는 것으로 보입니다.

 
console.log("Headers: " + data.XHR.getAllResponseHeaders()); 

로그는 실제로 서버에 의해 반환 된 헤더의 거의 보여줍니다 : 나는 쿼리 성공 콜백에 다음 추가 할 때

나는이 효과를 참조하십시오.

이 아마도 당신이의 Web.config에

 
<add name="Access-Control-Expose-Headers" value="X-InlineCount" /> 

를 추가 할 때, 서버는 자바 스크립트 클라이언트에 "X-InlineCount"헤더를 노출 확인되는 브라우저를 알 수 있습니다.

나는 그 가능성을 조사하지 않았다고 고백한다; 아마도 단기적으로 실행 가능한 해결 방법 일 것입니다.

하지만 우리가 염려하는 한 밴드 측근 일뿐입니다. 우리는 개발자가 이런 종류의 것에 대해 걱정할 필요가 없다. CORS는 그대로 두통을 만듭니다. 따라서 헤더보다는 페이로드에 inlineCount을 전달하고이 문제를 모두 제거하십시오.

+0

알았어. 잘 됐네. 인라인 - 카운트가 헤더에있는 이유는 내게 의미가 없습니다. 결과 세트에서 찾고 있던 것을 실제로 깨닫기까지는 다소 시간이 걸렸습니다. – Sam