programing

페이지의 모든 AJAX 요청에 "훅" 추가

lastcode 2023. 3. 28. 21:49
반응형

페이지의 모든 AJAX 요청에 "훅" 추가

모든 AJAX 요청(송신 직전 또는 이벤트 중 하나)에 "훅"하여 액션을 수행할 수 있는지 알고 싶습니다.이 시점에서는 페이지에 다른 서드파티 스크립트가 있다고 가정합니다.이들 중 일부는 jQuery를 사용하는 반면 다른 일부는 사용하지 않습니다.이게 가능합니까?

메모: 승인된 답변은 호출이 너무 빨랐기 때문에 실제 응답을 얻을 수 없습니다.

이를 통해 일반적으로 모든 AJAX를 글로벌하게 대행 수신하고 서드파티 AJAX 라이브러리에 의해 할당되었을 가능성이 있는 콜백 등을 망치지 않습니다.

(function() {
    var origOpen = XMLHttpRequest.prototype.open;
    XMLHttpRequest.prototype.open = function() {
        console.log('request started!');
        this.addEventListener('load', function() {
            console.log('request completed!');
            console.log(this.readyState); //will always be 4 (ajax is completed successfully)
            console.log(this.responseText); //whatever the response was
        });
        origOpen.apply(this, arguments);
    };
})();

여기서 addEventListener API를 사용하여 수행할 수 있는 작업에 대한 기타 문서는 다음과 같습니다.

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Monitoring_progress

(이 방법은 작동하지 않습니다<= IE8).

아비브의 대답에 영감을 받아 조사를 좀 해봤는데, 이것이 내가 생각해낸 것이다.
스크립트의 코멘트에 의하면, 이것이 그렇게 도움이 되는지는 잘 모르겠습니다.물론 네이티브 XMLHttpRequest 객체를 사용하는 브라우저에서만 동작합니다.
가능하면 네이티브 오브젝트를 사용하기 때문에 javascript 라이브러리가 사용되면 될 것 같습니다.

function addXMLRequestCallback(callback){
    var oldSend, i;
    if( XMLHttpRequest.callbacks ) {
        // we've already overridden send() so just add the callback
        XMLHttpRequest.callbacks.push( callback );
    } else {
        // create a callback queue
        XMLHttpRequest.callbacks = [callback];
        // store the native send()
        oldSend = XMLHttpRequest.prototype.send;
        // override the native send()
        XMLHttpRequest.prototype.send = function(){
            // process the callback queue
            // the xhr instance is passed into each callback but seems pretty useless
            // you can't tell what its destination is or call abort() without an error
            // so only really good for logging that a request has happened
            // I could be wrong, I hope so...
            // EDIT: I suppose you could override the onreadystatechange handler though
            for( i = 0; i < XMLHttpRequest.callbacks.length; i++ ) {
                XMLHttpRequest.callbacks[i]( this );
            }
            // call the native send()
            oldSend.apply(this, arguments);
        }
    }
}

// e.g.
addXMLRequestCallback( function( xhr ) {
    console.log( xhr.responseText ); // (an empty string)
});
addXMLRequestCallback( function( xhr ) {
    console.dir( xhr ); // have a look if there is anything useful here
});

당신이 jquery를 언급했으니까, jquery가 제공하는 것은 알고 있습니다..ajaxSetup()다음과 같은 이벤트 트리거를 포함하는 글로벌 에이잭스 옵션을 설정하는 메서드success,error,그리고.beforeSend- 당신이 찾고 있는 것처럼 들리네요

$.ajaxSetup({
    beforeSend: function() {
        //do stuff before request fires
    }
});

물론 이 솔루션을 사용하려는 페이지에서 jQuery의 가용성을 확인해야 합니다.

Github에서 작업을 잘 하는 좋은 라이브러리를 찾았습니다.다른 js 파일보다 먼저 포함시켜야 합니다.

https://github.com/jpillora/xhook

다음으로, 임의의 착신 응답에 http 헤더를 추가하는 예를 나타냅니다.

xhook.after(function(request, response) {
  response.headers['Foo'] = 'Bar';
});

"mouw"라는 답변을 사용하여 요청 결과를 보고 싶다면 다음 솔루션을 사용할 것을 제안합니다.

function addXMLRequestCallback(callback) {
    var oldSend, i;
    if( XMLHttpRequest.callbacks ) {
        // we've already overridden send() so just add the callback
        XMLHttpRequest.callbacks.push( callback );
    } else {
        // create a callback queue
        XMLHttpRequest.callbacks = [callback];
        // store the native send()
        oldSend = XMLHttpRequest.prototype.send;
        // override the native send()
        XMLHttpRequest.prototype.send = function() {
            // call the native send()
            oldSend.apply(this, arguments);

            this.onreadystatechange = function ( progress ) {
               for( i = 0; i < XMLHttpRequest.callbacks.length; i++ ) {
                    XMLHttpRequest.callbacks[i]( progress );
                }
            };       
        }
    }
}

addXMLRequestCallback( function( progress ) {
    if (typeof progress.srcElement.responseText != 'undefined' &&                        progress.srcElement.responseText != '') {
        console.log( progress.srcElement.responseText.length );
    }
});

그것을 하는 데는 요령이 있다.

모든 스크립트를 실행하기 전에 원래 XHMTpReuqest 개체를 가져와 다른 var에 저장합니다.그런 다음 원래 XMLHttpRequest를 덮어쓰고 모든 콜을 자신의 오브젝트를 통해 전송합니다.

Psuedo 코드:

 var savd = XMLHttpRequest;
 XMLHttpRequest.prototype = function() {
     this.init = function() {
     }; // your code
     etc' etc'
 };

Youw의 답변 외에 XHR 콜을 대행 수신하는 iframe에 코드를 삽입하여 위의 답변을 사용했습니다.하지만, 나는 바뀌어야 했다.

XMLHttpRequest.prototype.send = function(){

수신인:

XMLHttpRequest.prototype.send = function(body)

그리고 나는 변해야 했다

oldSend.apply(this, arguments);

수신인:

oldSend.call(this, body);

이것은 IE8 문서모드가 있는 IE9에서 동작하기 위해서 필요했습니다.이 변경을 하지 않으면 컴포넌트 프레임워크(Visual WebGUI)에 의해 생성된 콜백이 일부 기능하지 않습니다.자세한 내용은 다음 링크를 참조하십시오.

이러한 수정이 없으면 AJAX 포스트백은 종료되지 않습니다.

쿼리...

<script>
   $(document).ajaxSuccess(
        function(event, xhr, settings){ 
          alert(xhr.responseText);
        }
   );
</script>

언급URL : https://stackoverflow.com/questions/5202296/add-a-hook-to-all-ajax-requests-on-a-page

반응형