2011-01-04 3 views
2

file: 프로토콜로 호스팅되는 자바 스크립트 앱을 작성하고 있습니다 (예 : 애플리케이션이 html, css 및 javascript 폴더 만 내 하드에 둡니다). 드라이브). 정상적인 XHR 요청을 시도하면 동일한 원산지 정책으로 인해 실패합니다.파일에 json/jsonp xhr 요청하기 :

제 질문은 이것이 위와 같이 앱으로 json/jsonp 파일을 요청하는 가장 좋은 방법입니다.

참고 : 지금까지 하드 코드 된 콜백 함수를 사용하여 jsonp 파일을 모두 가지고 있지만 이러한 요청에 대해 동적 콜백 함수를 사용하고 싶습니다.이 작업을 수행 할 수있는 방법이 있습니다. ?

+0

브라우저 요구 사항이 있습니까? – Hemlock

+2

가능한 한 많은 브라우저에서 작동해야합니다. – erikvold

+0

CORS를 사용하면'file :'호스트를 요청하여'Access-Control-Allow-Origin' 헤더를 반환 할 수 없기 때문에 결코 작동하지 않을 것입니다. – inf3rno

답변

5

이것은 일종의 일종의 일이지만 동적 콜백을 갖습니다. 기본적으로 그것은 file: 이전이 꽤 빠를 것이라는 사실에 의거합니다. 요청 대기열을 설정하고 한 번에 하나씩 보냅니다. 이것이 올바른 응답과 콜백이 보증 된 순서로 연결될 수 있는지를 알아낼 수있는 유일한 방법이었습니다. 누군가가 더 나은 방법을 생각해 낼 수 있기를 바랍니다. 그러나 응답을 동적으로 생성 할 수 없으면 이것이 할 수있는 최선입니다.

var JSONP = { 
    queue: [], 
    load: function(file, callback, scope) { 
     var head = document.getElementsByTagName('head')[0]; 
     var script = document.createElement('script'); 
     script.type = "text/javascript"; 
     script.src = file; 
     head.appendChild(script); 
    }, 

    request: function(file, callback, scope) { 
     this.queue.push(arguments); 
     if (this.queue.length == 1) { 
      this.next(); 
     } 
    }, 

    response: function(json) { 
     var requestArgs = this.queue.shift(); 
     var file = requestArgs[0]; 
     var callback = requestArgs[1]; 
     var scope = requestArgs[2] || this; 
     callback.call(scope, json, file); 

     this.next(); 
    }, 

    next: function() { 
     if (this.queue.length) { 
      var nextArgs = this.queue[0]; 
      this.load.apply(this, nextArgs); 
     } 
    } 

}}; // URL, 보안상의 이유로이 내가

window.onload = function() { 
    JSONP.request('data.js', function(json, file) { alert("1 " + json.message); }); 
    JSONP.request('data.js', function(json, file) { alert("2 " + json.message); }); 
} 

Data.js

JSONP.response({ 
    message: 'hello' 
}); 
+0

@ 에릭 나는 그 가정을하지 않는다. 다음 요청을 보내기 전에 실제로 반환을 기다리고 있습니다. 대신, 나는 요청이 빨리 될 것이라는 가정을하고있다. 그러나 주문은 문제가되지 않습니다. – Hemlock

+0

@Erik ... 나는 또한 오류가 없다고 가정하고 있다고 가정합니다.) – Hemlock

+0

이것은 괜찮은 해결책입니다. 그러나 대기중인 요청을 필요로하지 않는 것을보고 싶지만, 당신이 말하는 것처럼'file :'을 사용할 때 그렇게 나쁘다. – erikvold

-2

"나는 때문에 동일 출처 정책 AFAICT의 그들이 실패 정상 XHR 요청을하려고하면"

... 아니, 나는 XHR 요청이 사용하기 때문에 그들이 실패 할 생각 HTTP 또는 HTTPS 웹 서버의 리소스를 요청하려면 . (http://en.wikipedia.org/wiki/XMLHttpRequest 참조).

웹 서버에 접속하지 않으면 XHR 요청을 (성공적으로) 만들 수 없습니다.

+0

Firefox에서 작동합니다. – erikvold

+0

이것은 Chrome의 오류입니다. XMLHttpRequest는 file : /// C : /ColdFusion8/wwwroot/test-app/data/index.json을로드 할 수 없습니다. Origin null은 Access-Control-Allow-Origin이 허용하지 않습니다. – erikvold

+2

@ Erik : 당신이 옳다는 '실용적인'목적으로 생각합니다. 공식적으로 XMLHttpRequest의 사양은 파일 프로토콜 (http://www.w3.org/TR/XMLHttpRequest/)에 대한 언급을하지 않습니다. "일부 구현은 HTTP 및 HTTPS 외에 프로토콜을 지원하지만 그 기능은 다음과 같습니다. 이 명세서에서 다루지 않는 ". XMLHttpRequest가 같은 원본 정책으로 인해 실패했다고 말할 수 있습니다. 실제로 "일반적인 XHR 요청"이 아니 었습니다 ...공식 사양 (또는 위키 피 디아)에 따라 HTTP 또는 HTTPS가 포함되기 때문입니다. 나는 단지 학자이지만. :) – Gerrat

1

크롬이 파일에서 아약스 호출을 매우 엄격한 제한이를 테스트하기 위해 무슨 짓을

. 로컬에서 실행되는 앱이 중단된다는 점을 알고 있고 대체 방법에 대해서는 a lot of debate이 있지만 오늘날까지도 마찬가지입니다.

Ajax는 Firefox의 파일 URL에서 정상적으로 작동하지만 반환 코드는 http 상태 코드가 아닙니다. 즉 0은 성공하지만 200-299 + 304는 성공하지 못합니다.

IE는 Chrome과 Firefox의 보안 문제를 다르게 처리하며 다른 브라우저는 각각 고유 한 접근 방식을 사용합니다. 웹과 데스크톱 앱 사이의 경계는 매우 문제가되는 영역입니다.