Cách chặn tất cả các yêu cầu AJAX được thực hiện bởi các thư viện JS khác nhau


110

Tôi đang xây dựng một ứng dụng web với các thư viện JS khác nhau (AngularJS, OpenLayers, ...) và cần một cách để chặn tất cả các phản hồi AJAX để có thể, trong trường hợp phiên người dùng đã ghi đã hết hạn (phản hồi trở lại với 401 Unauthorizedtrạng thái), để chuyển hướng anh ta đến trang đăng nhập.

Tôi biết AngularJS cung cấp interceptorsđể quản lý các tình huống như vậy, nhưng không thể tìm ra cách để đạt được sự đưa vào các yêu cầu OpenLayers như vậy. Vì vậy, tôi đã chọn cách tiếp cận JS vani.

Ở đây tôi tìm thấy đoạn mã này ...

(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);

... mà tôi đã điều chỉnh và có vẻ như nó hoạt động như mong đợi (chỉ thử nghiệm nó trên Google Chrome cuối cùng).

Khi nó sửa đổi nguyên mẫu của XMLHTTPRequest, tôi tự hỏi điều này có thể gây nguy hiểm như thế nào hoặc liệu nó có thể tạo ra các vấn đề hiệu suất nghiêm trọng hay không. Và bằng cách này sẽ có bất kỳ thay thế hợp lệ?

Cập nhật: cách chặn các yêu cầu trước khi chúng được gửi đi

Thủ thuật trước hoạt động tốt. Nhưng điều gì sẽ xảy ra nếu trong cùng một kịch bản, bạn muốn chèn một số tiêu đề trước khi yêu cầu được gửi đi? Làm như sau:

(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
Có vẻ như hoàn toàn an toàn đối với tôi.
Barmar

Tác động hiệu suất duy nhất là nó sẽ chạy một chức năng bổ sung trong mỗi phản hồi AJAX, nhưng đó là những gì bạn muốn làm.
Barmar

Tôi đang tìm kiếm một cái gì đó như thế này. cảm ơn rất nhiều
Silver Moon

Câu trả lời:


36

Loại móc hàm này hoàn toàn an toàn và được thực hiện thường xuyên trên các phương pháp khác vì những lý do khác.

Và, tác động hiệu suất duy nhất thực sự chỉ là một lệnh gọi chức năng bổ sung cho mỗi lệnh .open()cộng với bất kỳ mã nào bạn tự thực thi mà có thể là không quan trọng khi có liên quan đến cuộc gọi mạng.


Trong IE, điều này sẽ không bắt bất kỳ mã nào cố gắng sử dụng ActiveXObjectphương pháp điều khiển để thực hiện Ajax. Mã được viết tốt đầu tiên sẽ tìm kiếm XMLHttpRequestđối tượng và sử dụng nó nếu có và đã có từ IE 7. Tuy nhiên, có thể có một số mã sử dụng ActiveXObjectphương thức này nếu nó có sẵn, điều này sẽ đúng trong các phiên bản IE sau này.


Trong các trình duyệt hiện đại, có nhiều cách khác để phát lệnh gọi Ajax chẳng hạn như fetch()giao diện, vì vậy nếu một người đang tìm cách kết nối tất cả các lệnh gọi Ajax, bạn phải kết nối nhiều hơn là chỉ XMLHttpRequest.


1
Xin chào @ jfriend00 - bạn sẽ kết nối tất cả các yêu cầu api tìm nạp như thế nào - stackoverflow.com/questions/44728723/… ?
colemerrick

1
@bagofcole - Có lẽ bạn có thể sửa fetch()chức năng này để chặn tất cả các lệnh gọi đến nó - mặc dù bản thân tôi chưa bao giờ thử điều đó. Có vẻ như mô-đun này làm được điều đó.
jfriend00

Phá vỡ YouTube khi cố gắng kết nối comment_service_ajaxcác yêu cầu.
Leeroy

3

Điều này sẽ không bắt được XMLHttpRequests đối với một số phiên bản IE (9 trở xuống) . Tùy thuộc vào thư viện, họ có thể tìm kiếm điều khiển ActiveX độc quyền của IE trước.

Và, tất nhiên, tất cả các cược sẽ tắt nếu bạn đang sử dụng DOCTYPE không nghiêm ngặt trong IE, nhưng tôi chắc rằng bạn biết điều đó.

Tham khảo: CanIuse


2

Như được chỉ ra bởi Firefox AMO Editor Rob W,

Đoạn mã sau thay đổi hành vi của XMLHttpRequest. Theo mặc định, nếu tham số thứ ba ("async") không được chỉ định, nó sẽ mặc định là true. Khi nó được chỉ định và không được xác định, nó tương đương với "false", biến một yêu cầu thành một yêu cầu HTTP đồng bộ. Điều này khiến giao diện người dùng bị chặn trong khi yêu cầu đang được xử lý và một số tính năng của API XMLHttpRequest cũng bị tắt.

...

Để sửa lỗi này, hãy thay thế open.call (....) bằng open.apply (this, các đối số);

Và đây là một liên kết tham khảo:

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


(trong đó "Đoạn mã sau" đề cập đến đoạn mã từ câu hỏi)
Rob W
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.