CORS가있는 IE9 jQuery AJAX가 "액세스가 거부되었습니다"를 반환합니다.


123

다음은 IE를 제외한 모든 브라우저에서 작동합니다 (IE 9에서 테스트 중입니다).

jQuery.support.cors = true;
...
        $.ajax(
            url + "messages/postMessageReadByPersonEmail",
            {
                crossDomain: true,
                data: {
                    messageId       : messageId,
                    personEmail     : personEmail
                },
                success: function() {
                    alert('marked as read');
                },
                error: function(a,b,c) {
                    alert('failed');
                },
                type: 'post'
            }
        );

을 사용하는 다른 함수가 dataType: 'jsonp'있지만이 AJAX 호출에서 반환 된 데이터가 필요하지 않습니다. 내 마지막 수단은 JSONP로 래핑 된 약간의 엉터리를 반환하는 것입니다.

IE가 데이터를 반환하지 않는 CORS 요청으로 망쳐 놓은 이유는 무엇입니까?


제안 된 답변 중 어느 것도 저에게 효과가 없었기 때문에 (쿠키를 CORS 요청에 전달해야했습니다. XDomainRequest를 사용할 때는 아니오입니다) 해결 방법은 다음과 같습니다. blog.gauffin.org/2014/04/… . 구조 대행 중! : p
— wimvds 2014 년

답변:


150

이것은 jQuery 의 알려진 버그 입니다. jQuery 팀은 "이를 핵심으로 지원할 계획이 없으며 플러그인으로 더 적합합니다." ( 이 주석 참조 ). IE는 XMLHttpRequest를 사용 하지 않고 XDomainRequest 라는 대체 개체를 사용합니다 .

가 있다 jQuery를에이 기능을 지원하는 데 사용할 플러그인, 여기에서 찾을 수 있습니다이 : https://github.com/jaubourg/ajaxHooks/blob/master/src/xdr.js

EDIT 이 기능 $.ajaxTransport은 운송업자 공장을 등록합니다. 전송자는 요청을 수행하기 위해 내부적 으로 사용됩니다 $.ajax. 따라서 평소처럼 전화 할 수 있어야 한다고 생각 합니다 $.ajax. 운송 업체 및 확장에 대한 정보는 여기$.ajax 에서 찾을 수 있습니다 .

또한이 플러그인의 더 나은 버전은 여기 에서 찾을 수 있습니다 .

다른 두 가지 참고 사항 :

  1. 개체 XDomainRequest는 IE8 에서 도입되었으며 아래 버전에서는 작동하지 않습니다.
  2. IE10에서 CORS는 일반 XMLHttpRequest를 사용하여 지원됩니다 .

편집 2 : http to https 문제

요청은 호스팅 페이지와 동일한 체계를 대상으로해야합니다.

이 제한은 AJAX 페이지가 http://example.com 에있는 경우 대상 URL도 HTTP로 시작해야 함을 의미합니다. 마찬가지로 AJAX 페이지가 https://example.com 에있는 경우 대상 URL도 HTTPS로 시작해야합니다.

출처 : http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx


12
플러그인의 "더 나은 버전"은 타고난 것입니다. 방금 내 페이지에 포함 시켰고 자동으로 $ .ajax 호출을 수정했습니다. :) 물론 필요한 모든 헤더 가 제자리에 있다고 가정 합니다.
— Kato

5
dennisg 답변에 추가하기 위해 xdr.js에는 버그가 있습니다-ajaxTransport 콜백은 그대로 호출되지 않습니다. stackoverflow.com/questions/12481560/… 에 따라 변경해야했습니다 (ajaxTransport 호출의 첫 번째 인수로 "+ *"추가).
— Volodymyr Otryshko 2013

4
jQuery.XDomainRequest.js는 현재 페이지와 원격 페이지가 모두 http 또는 https인지 확인합니다. 이것은 http 페이지에서 https API를 호출 할 수 없다는 것을 의미합니까?
— Aaron

2
moonscripts github repo에 연결된 코드가 작동하지 않는 이전 버전이라는 점은 주목할 가치가 있습니다. 최신 버전은 raw.github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest/…
— Clintm

3
@Aaron, @HariKaramSingh의 의견에 추가 : 프로토콜 ( http~ https), 도메인 ( google.com~ bing.com), 하위 도메인 ( mail.google.com~ maps.google.com) 또는 프로토콜 ( google.com:80-기본 포트 ~ google.com:8080)은 모두 "크로스 도메인"요청을 트리거합니다. 기본적으로 /URL 에서 첫 번째 앞의 모든 것은 동일해야합니다.
— allicarn 2014 년

62

@dennisg가 받아 들인 대답을 바탕으로 MoonScript의 jQuery.XDomainRequest.js 를 사용하여 성공적으로 수행했습니다 .

다음 코드는 Chrome, Firefox 및 IE10에서 올바르게 작동했지만 IE9에서는 실패했습니다. 스크립트를 포함하기 만하면 이제 IE9에서 자동으로 작동합니다. (아마 8 명이지만 테스트하지는 않았습니다.)

var displayTweets = function () {
    $.ajax({
        cache: false,
        type: 'GET',
        crossDomain: true,
        url: Site.config().apiRoot + '/Api/GetTwitterFeed',
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        success: function (data) {
            for (var tweet in data) {
                displayTweet(data[tweet]);
            }
        }
    });
};

3
jQuery.XDomainRequest.js 플러그인이 정확히 필요한 것입니다! HTTP 기본 인증 뒤의 요청에 대해 iexhr.js 플러그인을 사용할 수 없었지만 XDomainRequest는 매력적으로 작동했습니다!
— James Ford

이것은 나를 위해 일했습니다. 나는 Site.config (). apiRoot +가 필요하지 않았습니다 (내가 트위터 용이라고 가정하고 있습니다 ....) 그러나 이것은 훌륭하게 작동합니다. 감사합니다.
— Nicholas Decker

@NicholasDecker Site.config (). apiRoot는 보편적이거나 화려하지 않은 API의 루트 URL을 가져 오는 구현 특정 코드였습니다. 도움이되어 기쁩니다!
— JackMorrissey

나는 이것이 나를 위해 작동하기를 바랐지만 POST를 시도하고 있습니다. 그게 문제인지 궁금합니다.
— Jack Marchetti 2013

1
@cracker POST에만 문제가 있습니까? jQuery 후 스크립트가로드되고 호출이 MoonScript의 문서와 일치하는지 다시 확인하십시오.
— JackMorrissey 2014-06-16

16

"jQuery-ajaxTransport-XDomainRequest"플러그인을 사용하여이 작업을 수행하는 방법에 대한 전체 지침은 여기에서 찾을 수 있습니다. https://github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest#instructions

이 플러그인은 적극적으로 지원되며 HTML, JSON 및 XML을 처리합니다. 이 파일은 CDNJS에서도 호스팅되므로 추가 설정없이 스크립트를 페이지에 직접 드롭 할 수 있습니다. http://cdnjs.cloudflare.com/ajax/libs/jquery-ajaxtransport-xdomainrequest/1.0.1/jquery.xdomainrequest .min.js


1
이것은 훌륭하게 작동했습니다. 이 문제가 jQuery에 존재한다는 것은 믿을 수 없지만 ... 감사합니다!
— Cymen 2014 년

3

문제는 IE9 이하가 CORS를 지원하지 않는다는 것입니다. XDomainRequest는 GET / POST 및text/plain http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx에 설명 된대로 conten-type 합니다.

따라서 모든 HTTP 동사 및 / 또는 json 등을 사용하려면 다른 솔루션을 사용해야합니다. IE9 이하가 사용되는 경우 프록시로 정상적으로 다운 그레이드되는 프록시를 작성했습니다. ASP.NET을 사용하는 경우 코드를 전혀 변경할 필요가 없습니다.

해결책은 두 부분으로 나뉩니다. 첫 번째는 jQuery ajax 처리에 연결되는 jquery 스크립트입니다. crossDomain 요청이 이루어지고 브라우저가 IE 인 경우 자동으로 웹 서버를 호출합니다.

$.ajaxPrefilter(function (options, originalOptions, jqXhr) {
    if (!window.CorsProxyUrl) {
        window.CorsProxyUrl = '/corsproxy/';
    }
    // only proxy those requests
    // that are marked as crossDomain requests.
    if (!options.crossDomain) {
        return;
    }

    if (getIeVersion() && getIeVersion() < 10) {
        var url = options.url;
        options.beforeSend = function (request) {
            request.setRequestHeader("X-CorsProxy-Url", url);
        };
        options.url = window.CorsProxyUrl;
        options.crossDomain = false;
    }
});

웹 서버에서 요청을 수신하고 X-CorsProxy-Url http 헤더에서 값을 가져와 HTTP 요청을 수행하고 마지막으로 결과를 반환해야합니다.

내 블로그 게시물 : http://blog.gauffin.org/2014/04/how-to-use-cors-requests-in-internet-explorer-9-and-below/


1

지원되는 모든 브라우저 (IE7 + 및 일반)에 대한 유일한 솔루션이기 때문에 모든 요청을 JSONP로 작성 했습니다. 귀하의 답변은 기술적으로 IE9에서 작동하므로 올바른 답변을 얻을 수 있습니다.


2
이 문제가있는 모든 사람에게 참고하십시오.이 경우 <= IE7 요구 사항이 있고 서버를 제어 할 수없는 경우 (예 : JSONP가 포함 된 GET + 스크립트 태그를 지원하도록 만들 수 없음) 가장 좋은 방법은 JSONP 호출을 POST로 변환하고 블랙 박스 서버의 응답을 사용자에게 다시 스트리밍하는 경량 미들웨어 서버입니다.
— mikermcneil

1

MoonScript의 솔루션을 기반으로하는 대신 다음을 시도해 볼 수 있습니다.

https://github.com/intuit/xhr-xdr-adapter/blob/master/src/xhr-xdr-adapter.js

이점은 낮은 수준의 솔루션이기 때문에 jQuery뿐만 아니라 다른 프레임 워크와 함께 IE 8/9에서 CORS (가능한 범위까지)를 활성화 할 수 있다는 것입니다. AngularJS, jQuery 1.x 및 2.x와 함께 사용하는 데 성공했습니다.



0

이 문제를 해결하려면 ajax 파일에 .js가 포함되어 있는지 확인하십시오. ajax.php에 shadowbox.js를 포함하는 동안 액세스 거부 오류가 발생했습니다.


0

내 dev 컴퓨터에서 CORS 웹 서비스를 테스트하고 있었는데 IE에서만 "액세스가 거부되었습니다"라는 오류 메시지가 나타납니다. Firefox와 Chrome은 잘 작동했습니다. 이것은 ajax 호출에서 localhost를 사용했기 때문에 발생했습니다! 그래서 내 브라우저 URL은 다음과 같습니다.

http : //my_computer.my_domain.local/CORS_Service/test.html

test.html 내부의 ajax 호출은 다음과 같습니다.

//fails in IE 
$.ajax({
  url: "http://localhost/CORS_Service/api/Controller",
  ...
});

localhost 대신 컴퓨터 IP를 사용하도록 ajax 호출을 변경하면 모든 것이 작동했습니다.

//Works in IE
$.ajax({
  url: "http://192.168.0.1/CORS_Service/api/Controller",
  ...
});

IE 개발 도구 창 "네트워크"탭에는 CORS Preflight OPTIONS 요청과 XMLHttpRequest GET이 표시됩니다.이 요청은 제가 예상했던 그대로입니다.




-1

참고-참고

ajax의 URL에 " http://www.domain.xxx "또는 " http : // localhost / "또는 "IP >> 127.0.0.1"을 사용하지 마십시오 . 주소없이 경로 (디렉토리)와 페이지 이름 만 사용하십시오.

거짓 상태 :

var AJAXobj = createAjax();
AJAXobj.onreadystatechange = handlesAJAXcheck;
AJAXobj.open('POST', 'http://www.example.com/dir/getSecurityCode.php', true);
AJAXobj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
AJAXobj.send(pack);

진정한 상태 :

var AJAXobj = createAjax();
AJAXobj.onreadystatechange = handlesAJAXcheck;
AJAXobj.open('POST', 'dir/getSecurityCode.php', true);   // <<--- note
AJAXobj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
AJAXobj.send(pack);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.