วิธีสกัดกั้นคำขอ AJAX ทั้งหมดที่สร้างโดยไลบรารี JS ต่างๆ


110

ฉันกำลังสร้างเว็บแอปที่มีไลบรารี JS ที่แตกต่างกัน (AngularJS, OpenLayers, ... ) และต้องการวิธีสกัดกั้นการตอบสนองของ AJAX ทั้งหมดเพื่อให้สามารถใช้งานได้ในกรณีที่เซสชันผู้ใช้ที่บันทึกไว้หมดอายุ (การตอบกลับกลับมาพร้อมกับ401 Unauthorizedสถานะ) เพื่อเปลี่ยนเส้นทางเขา ไปที่หน้าเข้าสู่ระบบ

ฉันรู้ว่า AngularJS เสนอinterceptorsให้จัดการสถานการณ์ดังกล่าว แต่ไม่สามารถหาวิธีที่จะบรรลุการแทรกคำขอของ OpenLayers ได้ ดังนั้นฉันจึงเลือกใช้วิธี Vanilla 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 Chrome ครั้งล่าสุดเท่านั้น)

เนื่องจากมีการปรับเปลี่ยนต้นแบบของ XMLHTTPR ขอฉันสงสัยว่าสิ่งนี้อาจส่งผลอันตรายหรืออาจทำให้เกิดปัญหาด้านประสิทธิภาพที่ร้ายแรงได้หรือไม่ และจะมีทางเลือกอื่นที่ถูกต้องหรือไม่?

อัปเดต: วิธีสกัดกั้นคำขอก่อนส่ง

เคล็ดลับก่อนหน้าใช้งานได้โอเค แต่ถ้าในสถานการณ์เดียวกันคุณต้องการฉีดส่วนหัวบางส่วนก่อนที่จะส่งคำขอ? ดำเนินการดังต่อไปนี้:

(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

ฉันกำลังมองหาบางอย่างเช่นนี้ ขอบคุณมาก
Silver Moon

คำตอบ:


36

การติดตั้งฟังก์ชันประเภทนี้ปลอดภัยอย่างสมบูรณ์แบบและทำอย่างสม่ำเสมอด้วยวิธีการอื่น ๆ ด้วยเหตุผลอื่น ๆ

และผลกระทบด้านประสิทธิภาพเพียงอย่างเดียวคือการเรียกใช้ฟังก์ชันพิเศษเพียงอย่างเดียวสำหรับแต่ละ.open()รหัสที่คุณเรียกใช้ด้วยตัวเองซึ่งอาจไม่มีสาระสำคัญเมื่อมีการเรียกเครือข่าย


ใน IE สิ่งนี้จะไม่จับโค้ดใด ๆ ที่พยายามใช้ActiveXObjectวิธีควบคุมการทำ Ajax โค้ดที่เขียนอย่างดีจะมองหาXMLHttpRequestวัตถุเป็นอันดับแรกและใช้สิ่งนั้นหากมีและมีให้ตั้งแต่ IE 7 แต่อาจมีโค้ดบางตัวที่ใช้ActiveXObjectวิธีนี้หากมีให้ซึ่งจะเป็นจริงผ่าน IE เวอร์ชันที่ใหม่กว่ามาก


ในเบราว์เซอร์สมัยใหม่มีวิธีอื่น ๆ ในการเรียกใช้ Ajax เช่นไฟล์ fetch()อินเตอร์เฟซดังนั้นหากใครที่กำลังมองที่จะขอทุกสายอาแจ็กซ์, XMLHttpRequestคุณมีที่จะขอมากกว่าเพียงแค่


1
สวัสดี @ jfriend00 - คุณจะขอวิธีดึงข้อมูล API ทั้งหมดได้อย่างไร- stackoverflow.com/questions/44728723/… ?
colemerrick

1
@bagofcole - คุณน่าจะเป็นลิงปะfetch()ฟังก์ชั่นเพื่อสกัดกั้นการโทรทั้งหมด - แม้ว่าฉันจะไม่เคยลองด้วยตัวเองก็ตาม ดูเหมือนว่าโมดูลนี้จะทำเช่นนั้น
jfriend00

YouTube หยุดชะงักเมื่อพยายามcomment_service_ajaxขอ
Leeroy

3

สิ่งนี้จะไม่จับ XMLHttpRequests สำหรับ IE บางเวอร์ชัน(9 และต่ำกว่า)และด้านล่าง) พวกเขาอาจมองหา ActiveX control ที่เป็นกรรมสิทธิ์ของ IE ก่อนทั้งนี้ขึ้นอยู่กับไลบรารี

และแน่นอนว่าการเดิมพันทั้งหมดจะถูกปิดหากคุณใช้ DOCTYPE ที่ไม่เข้มงวดภายใต้ IE แต่ฉันแน่ใจว่าคุณรู้ดี

ข้อมูลอ้างอิง: CanIuse


2

ชี้เป็นความกรุณาโดยโดย Firefox AMO บรรณาธิการRob W,

โค้ดต่อไปนี้เปลี่ยนลักษณะการทำงานของ XMLHttpRequest โดยค่าเริ่มต้นหากไม่ได้ระบุพารามิเตอร์ที่สาม ("async") ค่าเริ่มต้นจะเป็นจริง เมื่อมีการระบุและไม่ได้กำหนดจะเทียบเท่ากับ "เท็จ" ซึ่งเปลี่ยนคำขอในคำขอ HTTP แบบซิงโครนัส สิ่งนี้ทำให้ UI ถูกบล็อกในขณะที่กำลังดำเนินการตามคำขอและคุณลักษณะบางอย่างของ XMLHttpRequest API จะถูกปิดใช้งานด้วย

...

ในการแก้ไขปัญหานี้ให้แทนที่ open.call (.... ) ด้วย open.apply (this, arguments);

และนี่คือลิงค์อ้างอิง:

https://xhr.spec.whatwg.org/#the-open()- วิธีการ


(โดยที่ "รหัสต่อไปนี้" หมายถึงตัวอย่างจากคำถาม)
Rob W
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.