ฉันจะเข้าถึงส่วนหัวการตอบสนอง HTTP ของหน้าผ่านทาง JavaScript ได้อย่างไร
เกี่ยวข้องกับคำถามนี้ซึ่งได้รับการแก้ไขเพื่อถามเกี่ยวกับการเข้าถึงส่วนหัว HTTP เฉพาะสองรายการ
ที่เกี่ยวข้อง:
ฉันจะเข้าถึงฟิลด์ส่วนหัวคำขอ HTTP ผ่าน JavaScript ได้อย่างไร
ฉันจะเข้าถึงส่วนหัวการตอบสนอง HTTP ของหน้าผ่านทาง JavaScript ได้อย่างไร
เกี่ยวข้องกับคำถามนี้ซึ่งได้รับการแก้ไขเพื่อถามเกี่ยวกับการเข้าถึงส่วนหัว HTTP เฉพาะสองรายการ
ที่เกี่ยวข้อง:
ฉันจะเข้าถึงฟิลด์ส่วนหัวคำขอ HTTP ผ่าน JavaScript ได้อย่างไร
คำตอบ:
ไม่สามารถอ่านส่วนหัวปัจจุบันได้ คุณสามารถขออีกครั้งเพื่อ URL เดียวกันและอ่านส่วนหัวของมัน แต่ไม่มีการรับประกันว่าส่วนหัวเท่ากับปัจจุบัน
ใช้รหัส JavaScript ต่อไปนี้เพื่อรับส่วนหัว HTTP ทั้งหมดโดยดำเนินการget
ตามคำขอ:
var req = new XMLHttpRequest();
req.open('GET', document.location, false);
req.send(null);
var headers = req.getAllResponseHeaders().toLowerCase();
alert(headers);
น่าเสียดายที่ไม่มี API ที่จะให้ส่วนหัวการตอบสนอง HTTP สำหรับคำขอหน้าเริ่มต้นของคุณ นั่นคือคำถามเดิมที่โพสต์ที่นี่ มันถูกถามซ้ำหลายครั้งเช่นกันเพราะบางคนต้องการรับส่วนหัวการตอบกลับที่แท้จริงของคำขอหน้าดั้งเดิมโดยไม่ต้องออกหน้าใหม่
หากมีการร้องขอ HTTP ทำผ่าน AJAX เป็นไปได้ที่จะได้รับส่วนหัวการตอบสนองด้วยgetAllResponseHeaders()
วิธีการ มันเป็นส่วนหนึ่งของ XMLHttpRequest API หากต้องการดูว่าสามารถใช้งานได้อย่างไรโปรดดูfetchSimilarHeaders()
ฟังก์ชั่นด้านล่าง โปรดทราบว่านี่เป็นการแก้ไขปัญหาที่ไม่น่าเชื่อถือสำหรับบางแอปพลิเคชัน
myXMLHttpRequest.getAllResponseHeaders();
API ถูกระบุในคำแนะนำผู้สมัครต่อไปนี้สำหรับ XMLHttpRequest: XMLHttpRequest - คำแนะนำผู้สมัคร W3C 3 สิงหาคม 2010
โดยเฉพาะgetAllResponseHeaders()
วิธีการที่ถูกระบุไว้ในส่วนต่อไปนี้: w3.org: XMLHttpRequest
คือgetallresponseheaders()
วิธีการ
เอกสาร MDN เป็นสิ่งที่ดีเกินไป: developer.mozilla.org:XMLHttpRequest
สิ่งนี้จะไม่ให้ข้อมูลเกี่ยวกับส่วนหัวการตอบกลับ HTTP ของคำขอหน้าต้นฉบับ แต่สามารถใช้เพื่อคาดเดาความรู้เกี่ยวกับส่วนหัวเหล่านั้นได้ เพิ่มเติมเกี่ยวกับที่อธิบายไว้ต่อไป
คำถามนี้ถูกถามครั้งแรกเมื่อหลายปีก่อนโดยถามเฉพาะเกี่ยวกับวิธีการรับส่วนหัวการตอบกลับ HTTP ดั้งเดิมสำหรับหน้าปัจจุบัน (เช่นหน้าเดียวกันภายในที่มีการเรียกใช้จาวาสคริปต์) นี่เป็นคำถามที่แตกต่างจากการรับส่วนหัวการตอบสนองสำหรับคำขอ HTTP ใด ๆ สำหรับคำขอหน้าเริ่มต้นส่วนหัวจะไม่พร้อมใช้งานจาวาสคริปต์ ไม่ว่าจะเป็นค่าส่วนหัวที่คุณต้องการจะเชื่อถือได้และสอดคล้องกันอย่างเพียงพอหรือไม่หากคุณขอหน้าเดียวกันอีกครั้งผ่าน AJAX จะขึ้นอยู่กับแอปพลิเคชันของคุณ
ต่อไปนี้เป็นคำแนะนำเล็กน้อยสำหรับการแก้ไขปัญหานั้น
หากการตอบสนองส่วนใหญ่คงที่และส่วนหัวไม่คาดว่าจะเปลี่ยนแปลงมากระหว่างคำขอคุณสามารถสร้างคำขอ AJAX สำหรับหน้าเดียวกันกับที่คุณอยู่ในปัจจุบันและสมมติว่าพวกเขาเป็นค่าเดียวกันซึ่งเป็นส่วนหนึ่งของหน้า การตอบสนอง HTTP สิ่งนี้จะช่วยให้คุณเข้าถึงส่วนหัวที่คุณต้องการโดยใช้ XMLHttpRequest API ที่ดีที่อธิบายไว้ข้างต้น
function fetchSimilarHeaders (callback) {
var request = new XMLHttpRequest();
request.onreadystatechange = function () {
if (request.readyState === XMLHttpRequest.DONE) {
//
// The following headers may often be similar
// to those of the original page request...
//
if (callback && typeof callback === 'function') {
callback(request.getAllResponseHeaders());
}
}
};
//
// Re-request the same page (document.location)
// We hope to get the same or similar response headers to those which
// came with the current page, but we have no guarantee.
// Since we are only after the headers, a HEAD request may be sufficient.
//
request.open('HEAD', document.location, true);
request.send(null);
}
วิธีการนี้จะเป็นปัญหาหากคุณต้องพึ่งพาค่าที่สอดคล้องกันระหว่างคำขอเนื่องจากคุณไม่สามารถรับประกันได้ว่าจะเหมือนกันทั้งหมด มันจะขึ้นอยู่กับแอปพลิเคชันเฉพาะของคุณและไม่ว่าคุณจะรู้ว่าคุณค่าที่คุณต้องการนั้นเป็นสิ่งที่จะไม่เปลี่ยนจากคำขอหนึ่งไปเป็นคำขอถัดไป
มีคุณสมบัติ BOM บางอย่าง (โมเดลวัตถุของเบราว์เซอร์) ซึ่งเบราว์เซอร์เป็นตัวกำหนดโดยดูที่ส่วนหัว คุณสมบัติเหล่านี้บางส่วนสะท้อนถึงส่วนหัว HTTP โดยตรง (เช่นnavigator.userAgent
ตั้งค่าเป็นค่าของUser-Agent
ฟิลด์ส่วนหัวHTTP ) ด้วยการดมกลิ่นของคุณสมบัติที่มีอยู่คุณอาจสามารถค้นหาสิ่งที่คุณต้องการหรือข้อมูลบางส่วนเพื่อระบุว่ามีการตอบกลับ HTTP ใดบ้าง
หากคุณควบคุมฝั่งเซิร์ฟเวอร์คุณสามารถเข้าถึงส่วนหัวที่คุณชอบในขณะที่คุณสร้างการตอบสนองแบบเต็ม สามารถส่งผ่านค่าไปยังไคลเอนต์ที่มีหน้าซึ่งถูกเก็บไว้ในมาร์กอัปหรือในโครงสร้าง JSON แบบอินไลน์ หากคุณต้องการให้ทุก ๆ ส่วนหัวของคำขอ HTTP พร้อมใช้งานกับจาวาสคริปต์ของคุณคุณสามารถทำซ้ำได้ในเซิร์ฟเวอร์และส่งกลับเป็นค่าที่ซ่อนอยู่ในมาร์กอัป อาจไม่ใช่วิธีที่ดีในการส่งค่าส่วนหัวด้วยวิธีนี้ แต่คุณสามารถทำได้อย่างแน่นอนสำหรับค่าเฉพาะที่คุณต้องการ วิธีแก้ปัญหานี้ก็ไม่มีประสิทธิภาพเช่นกัน แต่มันจะทำงานถ้าคุณต้องการมัน
การใช้XmlHttpRequest
คุณสามารถดึงหน้าปัจจุบันขึ้นมาจากนั้นตรวจสอบส่วนหัว http ของการตอบกลับ
กรณีที่ดีที่สุดคือทำHEAD
ตามคำขอจากนั้นตรวจสอบส่วนหัว
สำหรับตัวอย่างของการทำเช่นนี้ดูที่http://www.jibbering.com/2002/4/httprequest.html
แค่ 2 เซ็นต์ของฉัน
พนักงานบริการสามารถเข้าถึงข้อมูลเครือข่ายซึ่งรวมถึงส่วนหัว ส่วนที่ดีคือมันใช้งานได้กับทุกชนิดของการร้องขอไม่เพียง แต่
fetch
ร้องขอด้วยrespondWith
ฟังก์ชันpostMessage
ฟังก์ชั่นพนักงานบริการค่อนข้างเข้าใจยากดังนั้นฉันจึงสร้างห้องสมุดเล็ก ๆ เพื่อทำสิ่งนี้ มันสามารถใช้ได้บน GitHub: https://github.com/gmetais/sw-get-headers
สำหรับผู้ที่กำลังมองหาวิธีที่จะแยกส่วนหัว HTTP ทั้งหมดลงในวัตถุที่สามารถเข้าถึงได้เป็นพจนานุกรมheaders["content-type"]
ฉันได้สร้างฟังก์ชั่นparseHttpHeaders
:
function parseHttpHeaders(httpHeaders) {
return httpHeaders.split("\n")
.map(x=>x.split(/: */,2))
.filter(x=>x[0])
.reduce((ac, x)=>{ac[x[0]] = x[1];return ac;}, {});
}
var req = new XMLHttpRequest();
req.open('GET', document.location, false);
req.send(null);
var headers = parseHttpHeaders(req.getAllResponseHeaders());
// Now we can do: headers["content-type"]
อีกวิธีในการส่งข้อมูลส่วนหัวไปยัง JavaScript ก็คือผ่านคุกกี้ เซิร์ฟเวอร์สามารถดึงข้อมูลใดก็ได้ที่ต้องการจากส่วนหัวคำขอและส่งกลับไปยังSet-Cookie
ส่วนหัวการตอบกลับและสามารถอ่านคุกกี้ได้ใน JavaScript อย่างที่ keparo พูดว่ามันเป็นการดีที่สุดที่จะทำสิ่งนี้เพื่อหัวหนึ่งหรือสองหัวแทนที่จะทำเพื่อพวกเขาทั้งหมด
หากเรากำลังพูดถึงส่วนหัวขอคุณสามารถสร้างส่วนหัวของคุณเองเมื่อทำ XmlHttpRequests
var request = new XMLHttpRequest();
request.setRequestHeader("X-Requested-With", "XMLHttpRequest");
request.open("GET", path, true);
request.send(null);
คุณไม่สามารถเข้าถึงส่วนหัว http ได้ แต่ข้อมูลบางอย่างที่ให้ไว้ในนั้นมีอยู่ใน DOM ตัวอย่างเช่นหากคุณต้องการดู http referer (sic) ให้ใช้ document.referrer อาจมีคนอื่นเช่นนี้สำหรับส่วนหัว http อื่น ๆ ลองใช้ googling ในสิ่งที่คุณต้องการเช่น "http referer javascript"
ฉันรู้ว่าสิ่งนี้ควรชัดเจน แต่ฉันค้นหาสิ่งต่าง ๆ เช่น "http headers javascript" ทุกครั้งที่ฉันต้องการจริงๆคือผู้อ้างอิงและไม่ได้ผลลัพธ์ที่มีประโยชน์ใด ๆ ฉันไม่รู้ว่าฉันไม่ทราบหรือไม่ว่าฉันสามารถสืบค้นเฉพาะเจาะจงได้
เช่นเดียวกับคนจำนวนมากฉันขุดเน็ตโดยไม่มีคำตอบจริง :(
ฉันยังคงหาทางหลีกเลี่ยงที่จะช่วยเหลือผู้อื่นได้ ในกรณีของฉันฉันควบคุมเว็บเซิร์ฟเวอร์ของฉันอย่างเต็มที่ อันที่จริงมันเป็นส่วนหนึ่งของใบสมัครของฉัน (ดูการอ้างอิงท้าย) มันง่ายสำหรับฉันที่จะเพิ่มสคริปต์ในการตอบสนอง http ของฉัน ฉันปรับเปลี่ยนเซิร์ฟเวอร์ httpd ของฉันเพื่อฉีดสคริปต์เล็ก ๆ ภายในหน้า html ทุกหน้า ฉันดันบรรทัด 'js script' เพิ่มเติมหลังจากสร้างส่วนหัวของฉันแล้วซึ่งตั้งค่าตัวแปรที่มีอยู่จากเอกสารของฉันในเบราว์เซอร์ของฉัน [ฉันเลือกสถานที่] แต่มีตัวเลือกอื่น ๆ ที่เป็นไปได้ ในขณะที่เซิร์ฟเวอร์ของฉันเขียนใน nodejs ฉันไม่สงสัยเลยว่าเทคนิคเดียวกันสามารถใช้จาก PHP หรืออื่น ๆ
case ".html":
response.setHeader("Content-Type", "text/html");
response.write ("<script>location['GPSD_HTTP_AJAX']=true</script>")
// process the real contend of my page
ตอนนี้ทุกหน้า HTML โหลดจากเซิร์ฟเวอร์ของฉันให้สคริปต์นี้ดำเนินการโดยเบราว์เซอร์ที่แผนกต้อนรับ ฉันสามารถตรวจสอบจาก JavaScript ได้อย่างง่ายดายถ้ามีตัวแปรอยู่หรือไม่ ใน usecase ของฉันฉันต้องรู้ว่าฉันควรใช้โปรไฟล์ JSON หรือ JSON-P เพื่อหลีกเลี่ยงปัญหา CORS แต่สามารถใช้เทคนิคเดียวกันเพื่อวัตถุประสงค์อื่น [เช่น: เลือกระหว่างเซิร์ฟเวอร์การพัฒนา / การผลิตรับจากเซิร์ฟเวอร์ REST / API รหัส ฯลฯ .... ]
ในเบราว์เซอร์คุณเพียงแค่ต้องตรวจสอบตัวแปรโดยตรงจาก JavaScript เช่นในตัวอย่างของฉันที่ฉันใช้มันเพื่อเลือกโปรไฟล์ Json / JQuery ของฉัน
// Select direct Ajax/Json profile if using GpsdTracking/HttpAjax server otherwise use JsonP
var corsbypass = true;
if (location['GPSD_HTTP_AJAX']) corsbypass = false;
if (corsbypass) { // Json & html served from two different web servers
var gpsdApi = "http://localhost:4080/geojson.rest?jsoncallback=?";
} else { // Json & html served from same web server [no ?jsoncallback=]
var gpsdApi = "geojson.rest?";
}
var gpsdRqt =
{key :123456789 // user authentication key
,cmd :'list' // rest command
,group :'all' // group to retreive
,round : true // ask server to round numbers
};
$.getJSON(gpsdApi,gpsdRqt, DevListCB);
สำหรับผู้ที่ต้องการตรวจสอบรหัสของฉัน: https://www.npmjs.org/package/gpsdtracking
ใช้ mootools คุณสามารถใช้ this.xhr.getAllResponseHeaders ()
ฉันเพิ่งทดสอบและสิ่งนี้ใช้ได้กับฉันโดยใช้ Chrome เวอร์ชัน 28.0.1500.95
ฉันต้องการดาวน์โหลดไฟล์และอ่านชื่อไฟล์ ชื่อไฟล์อยู่ในส่วนหัวดังนั้นฉันทำต่อไปนี้:
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.responseType = "blob";
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
success(xhr.response); // the function to proccess the response
console.log("++++++ reading headers ++++++++");
var headers = xhr.getAllResponseHeaders();
console.log(headers);
console.log("++++++ reading headers end ++++++++");
}
};
เอาท์พุท:
Date: Fri, 16 Aug 2013 16:21:33 GMT
Content-Disposition: attachment;filename=testFileName.doc
Content-Length: 20
Server: Apache-Coyote/1.1
Content-Type: application/octet-stream
นี่คือสคริปต์ของฉันเพื่อรับส่วนหัวการตอบสนองทั้งหมด:
var url = "< URL >";
var req = new XMLHttpRequest();
req.open('HEAD', url, false);
req.send(null);
var headers = req.getAllResponseHeaders();
//Show alert with response headers.
alert(headers);
มีผลส่วนหัวการตอบสนอง
นี่คือการทดสอบเปรียบเทียบโดยใช้ Hurl.it:
ในการรับส่วนหัวเป็นวัตถุซึ่งเป็น handier (ปรับปรุงคำตอบของราชา ):
var req = new XMLHttpRequest();
req.open('GET', document.location, false);
req.send(null);
var headers = req.getAllResponseHeaders().toLowerCase();
headers = headers.split(/\n|\r|\r\n/g).reduce(function(a, b) {
if (b.length) {
var [ key, value ] = b.split(': ');
a[key] = value;
}
return a;
}, {});
console.log(headers);
ลิงก์ของ Allain Lalonde ทำให้วันของฉัน เพียงเพิ่มรหัส html ที่ใช้งานได้ง่ายที่นี่
ทำงานร่วมกับเบราว์เซอร์ที่เหมาะสมตั้งแต่อายุบวกกับ IE9 + และ Presto-Opera 12
<!DOCTYPE html>
<title>(XHR) Show all response headers</title>
<h1>All Response Headers with XHR</h1>
<script>
var X= new XMLHttpRequest();
X.open("HEAD", location);
X.send();
X.onload= function() {
document.body.appendChild(document.createElement("pre")).textContent= X.getAllResponseHeaders();
}
</script>
หมายเหตุ: คุณได้รับส่วนหัวของคำขอที่สองผลลัพธ์อาจแตกต่างจากคำขอเริ่มต้น
fetch()
API ที่
ทันสมัยกว่า<!DOCTYPE html>
<title>fetch() all Response Headers</title>
<h1>All Response Headers with fetch()</h1>
<script>
var x= "";
if(window.fetch)
fetch(location, {method:'HEAD'})
.then(function(r) {
r.headers.forEach(
function(Value, Header) { x= x + Header + "\n" + Value + "\n\n"; }
);
})
.then(function() {
document.body.appendChild(document.createElement("pre")).textContent= x;
});
else
document.write("This does not work in your browser - no support for fetch API");
</script>
นี่เป็นคำถามเก่า ไม่แน่ใจว่าเมื่อการสนับสนุนมากขึ้นในวงกว้าง แต่getAllResponseHeaders()
และgetResponseHeader()
ปรากฏว่าในขณะนี้จะเป็นมาตรฐานเป็นธรรม: http://www.w3schools.com/xml/dom_http.asp
ตามที่ได้รับการกล่าวถึงแล้วถ้าคุณควบคุมฝั่งเซิร์ฟเวอร์ก็ควรส่งหัวเริ่มต้นคำขอกลับไปยังลูกค้าในการตอบสนองเริ่มต้น
ใน Express ตัวอย่างเช่นการทำงานต่อไปนี้:
app.get('/somepage', (req, res) => {
res.render('somepage.hbs', {headers: req.headers});
})
จากนั้นส่วนหัวจะพร้อมใช้งานภายในเทมเพลตดังนั้นอาจซ่อนได้ แต่รวมอยู่ในมาร์กอัพและอ่านโดย Javascript ของไคลเอนต์
ฉันคิดว่าคำถามผิดไปถ้าคุณต้องการใช้หัวข้อการร้องขอจาก JQuery / JavaScript คำตอบก็คือไม่ไม่โซลูชันอื่น ๆ คือการสร้างหน้า aspx หรือหน้า jsp จากนั้นเราสามารถเข้าถึงส่วนหัวคำขอได้อย่างง่ายดาย รับคำขอทั้งหมดในหน้า aspx และใส่ลงในเซสชั่น / คุกกี้จากนั้นคุณสามารถเข้าถึงคุกกี้ในหน้า JavaScript ..