다른 JS 라이브러리에서 만든 모든 AJAX 요청을 가로채는 방법


110

다른 JS 라이브러리 (AngularJS, OpenLayers, ...)를 사용하여 웹 앱을 구축 중이며 로깅 된 사용자 세션이 만료 된 경우 (응답이 401 Unauthorized상태로 돌아옴) 그를 리디렉션 할 수 있도록 모든 AJAX 응답을 가로 챌 수있는 방법이 필요합니다. 로그인 페이지로 이동합니다.

AngularJS가 interceptors이러한 시나리오를 관리 할 수 있다는 것을 알고 있지만 OpenLayers 요청에 이러한 주입을 달성하는 방법을 찾을 수 없었습니다. 그래서 저는 바닐라 JS 접근 방식을 선택했습니다.

여기서이 코드를 찾았습니다.

(function(open) {

    XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {

        this.addEventListener("readystatechange", function() {
            console.log(this.readyState); // this one I changed
        }, false);

        open.call(this, method, url, async, user, pass);
    };

})(XMLHttpRequest.prototype.open);

... 내가 적응했고 예상대로 작동하는 것처럼 보입니다 (마지막 Google 크롬에서만 테스트했습니다).

XMLHTTPRequest의 프로토 타입을 수정할 때 이것이 얼마나 위험한지 또는 심각한 성능 문제를 일으킬 수 있는지 궁금합니다. 그런데 유효한 대안이 있습니까?

업데이트 : 요청이 전송되기 전에 가로채는 방법

이전 트릭은 정상적으로 작동합니다. 그러나 동일한 시나리오에서 요청이 전송되기 전에 일부 헤더를 삽입하려면 어떻게해야합니까? 다음을 수행하십시오.

(function(send) {

    XMLHttpRequest.prototype.send = function(data) {

        // in this case I'm injecting an access token (eg. accessToken) in the request headers before it gets sent
        if(accessToken) this.setRequestHeader('x-access-token', accessToken);

        send.call(this, data);
    };

})(XMLHttpRequest.prototype.send);

4
나에게 완벽하게 안전한 것 같습니다.
Barmar

성능에 미치는 유일한 영향은 모든 AJAX 응답 중에 추가 기능을 실행한다는 것입니다.하지만 이것이 여러분이 원하는 것입니다.
Barmar

나는 이와 같은 것을 찾고 있었다. 덕분에 많은
실버 문

답변:


36

이러한 유형의 함수 후킹은 완벽하게 안전하며 다른 이유로 다른 방법에서 정기적으로 수행됩니다.

그리고 성능에 미치는 유일한 영향은 실제로 각각에 대해 하나의 추가 함수 호출 .open()과 네트워킹 호출이 관련 될 때 중요하지 않은 코드를 직접 실행하는 것입니다.


IE에서 이것은 ActiveXObjectAjax를 수행 하는 제어 방법 을 사용하려는 코드를 포착하지 않습니다 . 잘 작성된 코드는 먼저 XMLHttpRequest개체를 찾아서 사용할 수 있고 IE 7부터 사용할 수있는 ActiveXObject경우이를 사용합니다. 그러나 사용 가능한 경우 메서드 를 사용하는 코드가있을 수 있으며 이는 훨씬 최신 버전의 IE를 통해 적용됩니다.


최신 브라우저에서는 fetch()인터페이스 와 같은 Ajax 호출을 발행하는 다른 방법이 있으므로 모든 Ajax 호출을 후크하려는 경우 XMLHttpRequest.


1
안녕하세요 @ jfriend00을 - - 당신은 어떻게 모든 API 요청을 가져 후크 것 stackoverflow.com/questions/44728723/...를 ?
colemerrick

1
@bagofcole- fetch()내가 직접 시도한 적이 없지만 모든 호출을 가로 채기 위해 함수를 원숭이 패치 할 수 있습니다. 이 모듈 이 그렇게하는 것 같습니다 .
jfriend00

comment_service_ajax요청 을 연결하려고 할 때 YouTube를 중단 합니다.
Leeroy

3

일부 버전의 IE (9 이하) 에서는 XMLHttpRequests를 포착하지 못합니다 . 라이브러리에 따라 IE의 독점 ActiveX 컨트롤을 먼저 찾을 수 있습니다.

물론 IE에서 엄격하지 않은 DOCTYPE을 사용하는 경우 모든 베팅이 꺼져 있지만 알고 계실 것입니다.

참조 : CanIuse


2

Firefox AMO Editor가 친절하게 지적했듯이 Rob W,

다음 코드는 XMLHttpRequest의 동작을 변경합니다. 기본적으로 세 번째 ( "async") 매개 변수가 지정되지 않은 경우 기본값은 true입니다. 지정되고 정의되지 않은 경우 동기 HTTP 요청에서 요청을 전환하는 "false"와 동일합니다. 이로 인해 요청이 처리되는 동안 UI가 차단되고 XMLHttpRequest API의 일부 기능도 비활성화됩니다.

...

이 문제를 해결하려면 open.call (....)을 open.apply (this, arguments);

다음은 참조 링크입니다.

https://xhr.spec.whatwg.org/#the-open()-method


( "다음 코드는"질문에서 조각을 의미 임)
롭 W
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.