ส่วนหัวการตอบกลับ jQuery และ AJAX


163

ดังนั้นฉันจึงได้รับ jQuery AJAX นี้และการตอบสนองมาจากเซิร์ฟเวอร์ในรูปแบบ 302 redirect ฉันต้องการใช้การเปลี่ยนเส้นทางนี้และโหลดใน iframe แต่เมื่อฉันพยายามดูข้อมูลส่วนหัวด้วยการแจ้งเตือนจาวาสคริปต์มันจะเป็นโมฆะแม้ว่า firebug จะเห็นอย่างถูกต้อง

นี่คือรหัสถ้ามันจะช่วย:

$j.ajax({
    type: 'POST',
    url:'url.do',
    data: formData,
    complete: function(resp){
        alert(resp.getAllResponseHeaders());
    }
});

ฉันไม่สามารถเข้าถึงสิ่งที่ฝั่งเซิร์ฟเวอร์เพื่อย้าย URL ไปยังเนื้อหาการตอบสนองซึ่งฉันรู้ว่าจะเป็นทางออกที่ง่ายที่สุดดังนั้นความช่วยเหลือใด ๆ กับการแยกส่วนหัวจะยอดเยี่ยม


3
หากคุณกำลังเยี่ยมชมคำถามนี้ในปี 2560 หรือใหม่กว่าโปรดอย่าเสียเวลากับคำตอบที่มีอยู่ส่วนใหญ่ หากปัญหาของคุณเหมือนกับ OP คุณมีสองตัวเลือก: 1) ตั้งค่าพร็อกซีเซิร์ฟเวอร์ซึ่งจะpostเป็นเซิร์ฟเวอร์ดั้งเดิมและแยกข้อมูลเป้าหมายและ JS หน้า Front-end จะร้องขอพร็อกซีเซิร์ฟเวอร์นี้สำหรับข้อมูลเป้าหมาย หรือ 2) เปลี่ยนรหัสของเซิร์ฟเวอร์เพื่ออนุญาต CORS
kmonsoor

คำตอบ:


186

วิธีการแก้ปัญหาของ cballou จะทำงานได้ถ้าคุณใช้ jquery เวอร์ชันเก่า ในเวอร์ชันที่ใหม่กว่าคุณสามารถลอง:

  $.ajax({
   type: 'POST',
   url:'url.do',
   data: formData,
   success: function(data, textStatus, request){
        alert(request.getResponseHeader('some_header'));
   },
   error: function (request, textStatus, errorThrown) {
        alert(request.getResponseHeader('some_header'));
   }
  });

ตามเอกสารวัตถุ XMLHttpRequest มีให้บริการตั้งแต่ jQuery 1.4


5
ณ jQuery> = 1.5 ควรเรียกว่าjqXHRซึ่งเป็น superset ของวัตถุ XHR
Johan

136

หากนี่เป็นคำขอ CORSคุณอาจเห็นส่วนหัวทั้งหมดในเครื่องมือแก้ไขข้อบกพร่อง (เช่น Chrome-> ตรวจสอบองค์ประกอบ -> เครือข่าย) แต่วัตถุ xHR จะดึงเฉพาะส่วนหัว (ผ่านxhr.getResponseHeader('Header')) หากส่วนหัวนั้นเป็นส่วนหัวการตอบกลับแบบง่าย :

  • Content-Type
  • Last-modified
  • Content-Language
  • Cache-Control
  • Expires
  • Pragma

หากไม่ได้อยู่ในชุดนี้จะต้องแสดงอยู่ในAccess-Control-Expose-Headersหัวส่งคืนโดยเซิร์ฟเวอร์

เกี่ยวกับกรณีที่เป็นปัญหาหากเป็นคำขอ CORS เราจะสามารถดึงLocationส่วนหัวผ่านXMLHttpRequestวัตถุได้ถ้าหากส่วนหัวด้านล่างนี้มีอยู่ด้วย:

Access-Control-Expose-Headers: Location

หากไม่ใช่คำขอ CORS XMLHttpRequestจะไม่มีปัญหาในการเรียกคืน


3
@acdcjunior ขอบคุณมันช่วยฉันด้วยหลังจากฉันได้ใช้เวลาในการค้นหาว่าทำไมไม่มีผลลัพธ์ในการตอบสนองส่วนหัว
daniyel

33
 var geturl;
  geturl = $.ajax({
    type: "GET",
    url: 'http://....',
    success: function () {
      alert("done!"+ geturl.getAllResponseHeaders());
    }
  });

1
ไม่ได้ผลสำหรับฉัน ฉันอาจจะทำตามคำขอไปยังเว็บไซต์อื่น? (คำขอข้ามไซต์โดยใช้ ajax)
Siwei Shen 申思维

9
สำหรับคนที่ไม่สามารถทำงานได้เหมือนฉัน อาจเป็นเพราะคุณทำการเข้าถึงข้ามโดเมนซึ่ง jQuery ไม่ได้ใช้ XHR api.jquery.com/jQuery.get
h - n

สวยเหมือนมีเสน่ห์ .. +1
ErShakirAnsari

18

ความจริงที่โชคร้ายเกี่ยวกับ AJAX และการเปลี่ยนเส้นทาง 302 คือคุณไม่สามารถรับส่วนหัวจากการส่งคืนเนื่องจากเบราว์เซอร์ไม่เคยให้ XHR แก่พวกเขา เมื่อเบราว์เซอร์เห็น 302 มันจะใช้การเปลี่ยนเส้นทางโดยอัตโนมัติ ในกรณีนี้คุณจะเห็นส่วนหัวใน firebug เนื่องจากเบราว์เซอร์ได้รับมา แต่คุณจะไม่เห็นใน ajax เนื่องจากเบราว์เซอร์ไม่ผ่าน นี่คือเหตุผลที่ความสำเร็จและตัวจัดการข้อผิดพลาดไม่เคยถูกเรียก เรียกตัวจัดการที่สมบูรณ์เท่านั้น

http://www.checkupdown.com/status/E302.html

The 302 response from the Web server should always include an alternative URL to which redirection should occur. If it does, a Web browser will immediately retry the alternative URL. So you never actually see a 302 error in a Web browser

นี่คือโพสต์สแต็คโอเวอร์โฟลว์บางรายการในหัวเรื่อง บางโพสต์อธิบายแฮ็กเพื่อแก้ไขปัญหานี้

วิธีจัดการคำขอเปลี่ยนเส้นทางหลังจากการโทร jQuery Ajax

รับ 302 FOUND ใน JavaScript

การเปลี่ยนเส้นทาง HTTP: 301 (ถาวร) กับ 302 (ชั่วคราว)


10

วัตถุ XMLHttpRequest พื้นฐานที่ใช้โดย jQuery จะติดตามการเปลี่ยนเส้นทางอย่างเงียบ ๆแทนที่จะส่งคืนรหัสสถานะ 302 ดังนั้นคุณไม่สามารถใช้ฟังก์ชั่นร้องขอ AJAX ของ jQuery เพื่อรับ URL ที่ส่งคืน แต่คุณต้องใส่ข้อมูลทั้งหมดลงในแบบฟอร์มและส่งแบบฟอร์มโดยมีการตั้งค่าtargetแอตทริบิวต์เป็นค่าของnameแอตทริบิวต์ของ iframe:

$('#myIframe').attr('name', 'myIframe');

var form = $('<form method="POST" action="url.do"></form>').attr('target', 'myIframe');
$('<input type="hidden" />').attr({name: 'search', value: 'test'}).appendTo(form);

form.appendTo(document.body);
form.submit();

url.doหน้าของเซิร์ฟเวอร์จะถูกโหลดใน iframe แต่เมื่อสถานะของ 302 มาถึง iframe จะถูกเปลี่ยนเส้นทางไปยังปลายทางสุดท้าย


9

ลองนี้:

type: "GET",
async: false,
complete: function (XMLHttpRequest, textStatus) {
    var headers = XMLHttpRequest.getAllResponseHeaders();
}

อืมมม ขอบคุณมากสำหรับการตอบกลับ แต่นั่นก็ยังกลับมาเป็นโมฆะ ความคิดอื่น ๆ ?
เชน

บางทีคุณกำลังใช้ jQuery รุ่นเก่าอยู่
rovsen

6

ปรับปรุง 2018 สำหรับ JQUERY 3 และ LATER

ฉันรู้ว่านี่เป็นคำถามเก่า แต่ไม่มีวิธีแก้ปัญหาใดที่ใช้ได้สำหรับฉัน นี่คือวิธีแก้ปัญหาที่ใช้งานได้:

//I only created this function as I am making many ajax calls with different urls and appending the result to different divs
function makeAjaxCall(requestType, urlTo, resultAreaId){
        var jqxhr = $.ajax({
            type: requestType,
            url: urlTo
        });
        //this section is executed when the server responds with no error 
        jqxhr.done(function(){

        });
        //this section is executed when the server responds with error
        jqxhr.fail(function(){

        })
        //this section is always executed
        jqxhr.always(function(){
            console.log("getting header " + jqxhr.getResponseHeader('testHeader'));
        });
    }

2

+1 ถึง PleaseStand และนี่คือแฮ็กคนอื่นของฉัน:

หลังจากการค้นหาและพบว่า "คำขอข้ามอาแจ็กซ์" ไม่สามารถรับส่วนหัวการตอบสนองจากวัตถุ XHR ฉันก็ยอมแพ้ และใช้ iframe แทน

1. <iframe style="display:none"></iframe>
2. $("iframe").attr("src", "http://the_url_you_want_to_access")
//this is my aim!!!
3. $("iframe").contents().find('#someID').html()  
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.