IE9 jQuery AJAX พร้อม CORS ส่งกลับ "การเข้าถึงถูกปฏิเสธ"


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 นี้ ทางเลือกสุดท้ายของฉันคือส่งคืน jibberish ที่ห่อด้วย JSONP เพียงเพื่อให้มันใช้งานได้

มีความคิดว่าเหตุใด IE จึงจัดการกับคำขอ CORS ที่ไม่ส่งคืนข้อมูล


เนื่องจากไม่มีคำตอบใดที่เสนอให้ฉันได้ผล (ฉันต้องส่งคุกกี้ไปยังคำขอ CORS เช่นกันซึ่งเป็นข้อห้ามเมื่อใช้ XDomainRequest) นี่คือวิธีแก้ปัญหา : blog.gauffin.org/2014/04/… . มอบฉันทะให้การช่วยเหลือ! : p
wimvds

คำตอบ:


150

นี่คือบั๊กที่รู้จักกับ jQuery ทีม jQuery "ไม่มีแผนที่จะสนับสนุนสิ่งนี้ในแกนหลักและเหมาะกว่าเป็นปลั๊กอิน" (ดูความคิดเห็นนี้ ). IE ไม่ได้ใช้XMLHttpRequestแต่วัตถุทางเลือกชื่อXDomainRequest

มีเป็นปลั๊กอินพร้อมที่จะสนับสนุนใน jQuery ซึ่งสามารถพบได้ที่นี่ : https://github.com/jaubourg/ajaxHooks/blob/master/src/xdr.js

แก้ไข ฟังก์ชั่นนี้$.ajaxTransportลงทะเบียนโรงงานขนส่ง ขนย้ายจะใช้ภายในโดย$.ajaxการดำเนินการร้องขอ ดังนั้นฉันถือว่าคุณควรจะโทรได้$.ajaxตามปกติ ข้อมูลเกี่ยวกับการขนย้ายและการขยาย$.ajaxสามารถพบได้ที่นี่

นอกจากนี้อาจจะเป็นรุ่นที่ดีขึ้นของปลั๊กอินนี้สามารถพบได้ที่นี่

อีกสองบันทึก:

  1. XDomainRequest ออบเจ็กต์ถูกนำมาใช้จาก IE8และจะไม่ทำงานในเวอร์ชันด้านล่าง
  2. จาก IE10 ล ธ จะได้รับการสนับสนุนโดยใช้ XMLHttpRequest

แก้ไข 2: http เป็น 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

4
jQuery.XDomainRequest.js ตรวจสอบให้แน่ใจว่าเพจปัจจุบันและเพจระยะไกลเป็นทั้ง http หรือ https หมายความว่าคุณไม่สามารถโทรไปยัง https API จากหน้า http ได้หรือไม่?
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

62

จากคำตอบที่ยอมรับโดย @dennisg ฉันทำสิ่งนี้สำเร็จโดยใช้jQuery.XDomainRequest.jsโดย MoonScript

รหัสต่อไปนี้ทำงานได้อย่างถูกต้องใน 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 คือสิ่งที่ฉันต้องการจริงๆ! ฉันไม่สามารถรับปลั๊กอิน iexhr.js เพื่อทำงานสำหรับคำขอที่อยู่เบื้องหลัง HTTP Basic Authentication แต่ XDomainRequest ทำงานได้อย่างมีเสน่ห์!
James Ford

สิ่งนี้ได้ผลสำหรับฉัน ฉันไม่ต้องการ Site.config (). apiRoot + (ซึ่งฉันคิดว่าเป็นสำหรับ twitter ... ) แต่มันใช้งานได้ดีขอบคุณที่ทำสิ่งนี้
Nicholas Decker

@NicholasDecker Site.config () apiRoot เป็นเพียงการติดตั้งโค้ดเฉพาะเพื่อรับ URL รูทของ API ไม่มีอะไรเป็นสากลหรือแฟนซี ดีใจด้วย!
JackMorrissey

ฉันหวังว่านี่จะได้ผลสำหรับฉัน แต่ฉันกำลังพยายามโพสต์ สงสัยว่านั่นเป็นปัญหาสำหรับฉันหรือเปล่า
Jack Marchetti

1
@cracker คุณมีปัญหากับ POST หรือไม่? ตรวจสอบอีกครั้งว่าสคริปต์กำลังโหลดหลังจาก jQuery และการโทรของคุณตรงกับเอกสารของ MoonScript
JackMorrissey

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

3

ปัญหาคือ IE9 และต่ำกว่าไม่รองรับ CORS XDomainRequest รองรับเฉพาะ GET / POST และtext/plainconten-type ตามที่อธิบายไว้ที่นี่: http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx

ดังนั้นหากคุณต้องการใช้คำกริยา HTTP และ / หรือ json และอื่น ๆ คุณต้องใช้วิธีอื่น ฉันได้เขียนพร็อกซีซึ่งจะดาวน์เกรดเป็นพร็อกซีอย่างสง่างามหากใช้ IE9 หรือน้อยกว่า คุณไม่จำเป็นต้องเปลี่ยนรหัสของคุณเลยหากคุณใช้ ASP.NET

การแก้ปัญหาเป็นสองส่วน อันแรกคือสคริปต์ jquery ที่เชื่อมต่อกับการประมวลผล jQuery ajax มันจะเรียกเว็บเซิร์ฟเวอร์โดยอัตโนมัติหากมีการร้องขอ 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

ฉันเพิ่งส่งคำขอJSONPทั้งหมดเพราะเป็นโซลูชันเดียวสำหรับเบราว์เซอร์ที่รองรับทั้งหมดของเรา (IE7 + และปกติ) โปรดทราบว่าในทางเทคนิคแล้วคำตอบของคุณใช้ได้กับ IE9 ดังนั้นคุณจึงมีคำตอบที่ถูกต้อง


2
เพียงแค่แจ้งให้ทุกคนที่มีปัญหานี้ - ในกรณีนี้หากคุณมีข้อกำหนด <= IE7 และคุณไม่สามารถควบคุมเซิร์ฟเวอร์ได้ (เช่นไม่สามารถรองรับ GET + แท็กสคริปต์ที่มี JSONP) ของคุณ ทางออกที่ดีที่สุดคือเซิร์ฟเวอร์มิดเดิลแวร์น้ำหนักเบาซึ่งแปลการเรียก JSONP เป็น POST และสตรีมการตอบสนองจากเซิร์ฟเวอร์กล่องดำกลับไปยังผู้ใช้
mikermcneil

1

จากการสร้างโซลูชันโดย MoonScript คุณสามารถลองสิ่งนี้แทน:

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

ข้อดีคือเนื่องจากเป็นโซลูชันระดับล่างจึงจะเปิดใช้งาน CORS (ในระดับที่เป็นไปได้) บน IE 8/9 กับเฟรมเวิร์กอื่น ๆ ไม่ใช่เฉพาะกับ jQuery ฉันประสบความสำเร็จในการใช้ AngularJS รวมถึง jQuery 1.x และ 2.x


0

รับ JSON ข้ามโดเมนด้วย jQuery ใน Internet Explorer 8 และเวอร์ชันที่ใหม่กว่า

ลิงค์ที่มีประโยชน์มาก:

http://graphicmaniacs.com/note/getting-a-cross-domain-json-with-jquery-in-internet-explorer-8-and-later/

สามารถช่วยแก้ปัญหาในการส่งคืน json จากคำขอโดเมน X

หวังว่านี่จะช่วยใครสักคน


0

ในการแก้ปัญหานี้ให้ตรวจสอบด้วยว่าคุณได้รวม. js ไว้ในไฟล์ ajax ของคุณหรือไม่: ฉันได้รับข้อผิดพลาดการเข้าถึงถูกปฏิเสธในขณะที่รวม shadowbox.js ใน ajax.php ของฉัน


0

ฉันกำลังทดสอบบริการเว็บ CORS บนเครื่อง dev ของฉันและได้รับข้อความแสดงข้อผิดพลาด "การเข้าถึงถูกปฏิเสธ" ใน IE เท่านั้น Firefox และ Chrome ทำงานได้ดี ปรากฎว่าเกิดจากการที่ฉันใช้ localhost ในการโทร ajax! URL เบราว์เซอร์ของฉันจึงเป็นดังนี้:

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

และการโทร ajax ของฉันภายใน test.html เป็นดังนี้:

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

ทุกอย่างทำงานได้เมื่อฉันเปลี่ยนการโทร ajax เพื่อใช้ IP ของคอมพิวเตอร์แทน localhost

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

แท็บ "เครือข่าย" หน้าต่างเครื่องมือ dev ของ IE ยังแสดงคำขอ CORS Preflight OPTIONS ตามด้วย XMLHttpRequest GET ซึ่งเป็นสิ่งที่ฉันคาดหวังว่าจะเห็น




-1

หมายเหตุ - หมายเหตุ

ห้ามใช้ " http://www.domain.xxx " หรือ " http: // localhost / " หรือ "IP >> 127.0.0.1" สำหรับ URL ใน ajax ใช้เฉพาะเส้นทาง (ไดเร็กทอรี) และชื่อเพจที่ไม่มีที่อยู่

สถานะเท็จ:

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.