Web sayfasının HTTP Başlıklarına JavaScript ile erişme


Yanıtlar:


365

Mevcut başlıkları okumak mümkün değildir. Aynı URL'den başka bir istekte bulunabilir ve üstbilgilerini okuyabilirsiniz, ancak üstbilgilerin tam olarak geçerli olana eşit olduğuna dair bir garanti yoktur.


Bir getistek gerçekleştirerek tüm HTTP başlıklarını almak için aşağıdaki JavaScript kodunu kullanın :

var req = new XMLHttpRequest();
req.open('GET', document.location, false);
req.send(null);
var headers = req.getAllResponseHeaders().toLowerCase();
alert(headers);

58
Saeed, soru yazar için belki iyi .. Açıkçası o en iyisini bilir .. o yüklü kaynağın başlıklarını erişmez çünkü, ama yeni bir istekte tahmin iyi cevabı ne olduğunu ve kendisine yapılan
mykhal

18
Hangi başlığa bağlı olduğunuza bağlı olarak 'HEAD' fiilini kullanmak isteyebilirsiniz.
scottrudy

17
Yeni bir istekte bulunma, yalnızca ihtiyacınız olan yanıt değerlerinin bir talepten diğerine özdeş olması garanti edilirse işe yarayacaktır. Uygulamanıza bağlı olacaktır, bu nedenle böyle bir yaklaşımla kat ettiğiniz mesafe değişecektir.
keparo

6
Bu kesmek bazı senaryolarda çalışabilir, ancak komut dosyasını içeren sayfa bir POST isteğine yanıt olarak oluşturulduysa hiç işe yaramaz ve sunucunun bir hatayla karşılaşıp karşılaşmadığını belirlemeye çalışıyorsanız yardımcı olmaz (HTTP 5XX) orijinal isteği işlerken.
kilmation

9
Bu cevap çok yanlış. Doğru cevap "mümkün değil" dir. Ya da bu cevaba uyacak şekilde "Bu mümkün değil, ama sizin için hiç işe yaramayabilecek ya da olmayacak şekilde simüle etmeye çalışmak bir hack".
Ocak

301

Maalesef, ilk sayfa isteğiniz için HTTP yanıt başlıklarını verecek bir API yok. Burada yayınlanan asıl soru buydu. Bu edilmiş defalarca sorulan bazı insanlar başka bir veren olmadan orijinal sayfa isteği gerçek yanıt başlıklarını almak istiyorum, çünkü çok.


AJAX İstekleri için:

AJAX üzerinden bir HTTP isteği yapılırsa, getAllResponseHeaders()yöntemle yanıt başlıklarını almak mümkündür . XMLHttpRequest API'sinin bir parçasıdır. Bunun nasıl uygulanabileceğini görmek için fetchSimilarHeaders()aşağıdaki işlevi inceleyin. Bunun, bazı uygulamalar için güvenilir olmayacak soruna geçici bir çözüm olduğunu unutmayın.

myXMLHttpRequest.getAllResponseHeaders();

Bu, orijinal sayfa isteğinin HTTP yanıt üstbilgileri hakkında bilgi vermez, ancak bu üstbilgilerin ne olduğu konusunda eğitimli tahminler yapmak için kullanılabilir. Bununla ilgili daha fazla bilgi aşağıda açıklanmaktadır.


İlk Sayfa İsteğinden başlık değerlerini alma:

Bu soru ilk olarak birkaç yıl önce sorulmuştur, özellikle geçerli sayfanın orijinal HTTP yanıt başlıklarına nasıl girileceği sorulmuştur (yani içinde javascriptin çalıştığı aynı sayfa). Bu, herhangi bir HTTP isteği için yanıt üstbilgilerini almaktan oldukça farklı bir sorudur. İlk sayfa isteği için, üstbilgiler javascript tarafından kolayca kullanılamaz. Aynı sayfayı AJAX aracılığıyla tekrar talep ederseniz, ihtiyacınız olan başlık değerlerinin güvenilir ve yeterince tutarlı olup olmayacağı, uygulamanıza bağlı olacaktır.

Aşağıda, bu sorunun üstesinden gelmek için birkaç öneri bulunmaktadır.


1. Büyük ölçüde statik olan Kaynaklara İlişkin Talepler

Yanıt büyük ölçüde statikse ve başlıkların istekler arasında çok fazla değişmesi beklenmiyorsa, şu anda bulunduğunuz sayfa için AJAX isteği yapabilir ve bunların sayfanın bir parçası olan aynı değerler olduğunu varsayabilirsiniz. HTTP yanıtı. Bu, yukarıda açıklanan güzel XMLHttpRequest API'sini kullanarak ihtiyacınız olan başlıklara erişmenizi sağlayabilir.

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

İstekler arasında tutarlı olan değerlere gerçekten güvenmeniz gerekiyorsa, bu yaklaşım sorunlu olacaktır, çünkü bunların aynı olduğunu tam olarak garanti edemezsiniz. Bu, özel uygulamanıza ve ihtiyacınız olan değerin bir istekten diğerine değişmeyecek bir şey olup olmadığını bilmenize bağlı olacaktır.


2. Çıkarımlar Yapın

Orada bazı BOM özellikleri tarayıcı başlıklarını bakarak belirler (Tarayıcı Nesne Modeli). Bu özelliklerden bazıları doğrudan HTTP üstbilgilerini yansıtır (örneğin navigator.userAgent, HTTP User-Agentüstbilgisi alanının değerine ayarlanır ). Kullanılabilir özelliklerin etrafından dolaşarak neye ihtiyacınız olduğunu veya HTTP yanıtının ne içerdiğini belirtmek için bazı ipuçları bulabilirsiniz.


3. Onları sakla

Sunucu tarafını kontrol ederseniz, tam yanıtı oluştururken istediğiniz başlıklara erişebilirsiniz. Değerler, istemciye sayfa ile aktarılabilir, bazı biçimlendirmelerde veya belki de satır içi JSON yapısında saklanabilir. Javascript'iniz için her HTTP istek başlığının kullanılabilir olmasını istiyorsanız, bunları sunucuda tekrarlayabilir ve biçimlendirmede gizli değerler olarak geri gönderebilirsiniz. Üstbilgi değerlerini bu şekilde göndermek muhtemelen ideal değildir, ancak kesinlikle ihtiyacınız olan belirli bir değer için bunu yapabilirsiniz. Bu çözüm de tartışmasız verimsizdir, ancak ihtiyacınız varsa işi yapardı.


2
Google, burada açıkladığım gibi nasıl tespit etti: stackoverflow.com/questions/7191242/…
kamaci

RE güncelleme: ajax istekleri de 2008 yılında web geliştirme yolunun standart bir parçası oldu -_-
BlueRaja - Danny Pflughoeft

5
BOM merak edenler için "Tarayıcı Nesne Modeli" anlamına gelir. Arka plan için stackoverflow.com/questions/2213594/… adresine bakın .
Myrne Stol

1
3) http çerez başlığında da saklayabilirsiniz. Bu durumda belge işaretlemesini değiştirmeniz gerekmez.
skibulk

Bağlantı öğesi gibi yanıt başlığı öğelerine erişmenin basit bir yolu vardır: burada belge örneğini kullanın: gist.github.com/FunThomas424242/…
FunThomas424242


24

Servis Çalışanlarıyla Çözüm

Hizmet çalışanları, başlıkları içeren ağ bilgilerine erişebilir. İyi yanı, sadece XMLHttpRequest üzerinde değil, her türlü istekte çalışmasıdır.

Nasıl çalışır:

  1. Web sitenize bir servis çalışanı ekleyin.
  2. Gönderilen her isteği izleyin.
  3. Servis işçiye Make fetchile isteğirespondWith işlevle bulunun.
  4. Yanıt geldiğinde, başlıkları okuyun.
  5. postMessageFonksiyonu kullanarak hizmet çalışanından başlıkları sayfaya gönderin .

Çalışma örneği:

Servis çalışanları anlamak biraz karmaşık, bu yüzden tüm bunları yapan küçük bir kütüphane inşa ettim. Github'da mevcuttur: https://github.com/gmetais/sw-get-headers .

Sınırlamalar:

  • web sitesinin HTTPS'de olması gerekir
  • tarayıcının Servis Çalışanlarını desteklemesi gerekir API'sını
  • XMLHttpRequest'te olduğu gibi aynı etki alanı / etki alanları arası politikalar geçerlidir

12

Tüm HTTP üstbilgilerini sözlük olarak erişilebilen bir nesneye ayrıştırmanın bir yolunu arayanlar için headers["content-type"]bir işlev oluşturdum 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"]

10

Başlık bilgilerini JavaScript'e göndermenin başka bir yolu da çerezler kullanmaktır. Sunucu, istek üstbilgilerinden ihtiyaç duyduğu tüm verileri ayıklayabilir ve Set-Cookieyanıt başlığına geri gönderebilir ve çerezler JavaScript'te okunabilir. Yine de keparo'nun dediği gibi, bunu hepsi için değil, sadece bir veya iki başlık için yapmak en iyisidir.


1
Bu yaklaşım hala JS'niz için sunucuyu kontrol etmenizi gerektirir. Bu bilgiyi nasıl iletirseniz iletin, kodunuz birdenbire önbelleğe alınamaz hale getirildi. Orijinal varlığa yönelik talebi bozmamak için neden yalnızca belirli bir istek için bir API oluşturmuyorsunuz?
MST

5

İstek üstbilgilerinden bahsediyorsak , XmlHttpRequests yaparken kendi üstbilgilerinizi oluşturabilirsiniz.

var request = new XMLHttpRequest();
request.setRequestHeader("X-Requested-With", "XMLHttpRequest");
request.open("GET", path, true);
request.send(null);

güvenlik nedeniyle mozilla'daki istek üstbilgisini değiştiremezsiniz. mxr.mozilla.org/mozilla1.8.0/source/extensions/xmlextras/base/…
user121196 12:09

1
SetRequestHeader () yöntemini kullanmadan önce open () öğesini çağırmalısınız. developer.mozilla.org/tr/…
XP1

1
Erişim, asıl soruda, üstbilgileri ayarlamakla değil, üstbilgileri almakla ilgilidir.
Timo Tijhof

4

Http başlıklarına erişemezsiniz, ancak bunlarda sağlanan bazı bilgiler DOM'da bulunur. Örneğin, http yönlendiricisini (sic) görmek istiyorsanız document.referrer komutunu kullanın. Diğer http başlıkları için böyle başkaları olabilir. "Http referer javascript" gibi istediğiniz belirli bir şeyi Google'da aramayı deneyin.

Bunun açık olması gerektiğini biliyorum, ama gerçekten istediğim tek şey referans oldu ve herhangi bir yararlı sonuç alamadım "http headers javascript" gibi şeyler aramaya devam etti. Daha spesifik bir sorgu yapabileceğimi nasıl anlayacağımı bilmiyorum.


4

Birçok insan gibi ben de net bir cevap olmadan ağı kazıyorum :(

Yine de başkalarına yardımcı olabilecek bir bypass buluyorum. Benim durumumda web sunucumu tamamen kontrol ediyorum. Aslında benim uygulamamın bir parçası (son referansa bakın). Http yanıtıma bir komut dosyası eklemek benim için kolaydır. Her html sayfasında küçük bir komut dosyası enjekte etmek için httpd sunucumu değiştirdim. Yalnızca üstbilgim yapımdan hemen sonra, tarayıcımdaki [konumu seçiyorum] dokümanımdaki mevcut bir değişkeni ayarlayan fazladan bir 'js komut dosyası' satırı itiyorum, ancak başka bir seçenek mümkün. Sunucum nodejs ile yazılmış olsa da, aynı tekniğin PHP veya diğerlerinden kullanılabileceğinden şüphem yok.

  case ".html":
    response.setHeader("Content-Type", "text/html");
    response.write ("<script>location['GPSD_HTTP_AJAX']=true</script>")
    // process the real contend of my page

Şimdi sunucumdan yüklenen her html sayfası, bu komut dosyasını tarayıcı tarafından tarayıcıda çalıştırsın. Daha sonra değişkenin olup olmadığını kolayca JavaScript'ten kontrol edebilirim. Benim kullanımımda CORS sorununu önlemek için JSON veya JSON-P profilini kullanmam gerekip gerekmediğini bilmeliyim, ancak aynı teknik başka amaçlar için de kullanılabilir [yani: geliştirme / üretim sunucusu arasında seçim yapın, sunucudan bir REST / API alın anahtar, vb ....]

Tarayıcıda, değişkenimi doğrudan JavaScript'ten kontrol etmem gerekiyor, örneğin Json / JQuery profilimi seçmek için kullandığım örnekte olduğu gibi

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

Kodumu kim kontrol etmek isterse: https://www.npmjs.org/package/gpsdtracking


3

Mootools kullanarak, this.xhr.getAllResponseHeaders () öğesini kullanabilirsiniz.


3

Az önce test ettim ve bu benim için Chrome Sürüm 28.0.1500.95'i kullanarak çalışıyor.

Bir dosya indirip dosya adını okumam gerekiyordu. Dosya adı başlıkta, bu yüzden aşağıdakileri yaptım:

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 ++++++++");

    }
};

Çıktı:

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

2

Bu benim tüm yanıt başlıklarını almak için benim komut dosyasıdır:

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

Sonuç olarak yanıt başlıkları.

resim açıklamasını buraya girin

Bu Hurl.it kullanan bir karşılaştırma testidir:

resim açıklamasını buraya girin


2

Başlıkları daha kullanışlı bir nesne olarak almak için ( Raja'nın cevabının iyileştirilmesi ):

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

2

Allain Lalonde'un bağlantısı benim günümü yaptı. Sadece burada bazı basit çalışma html kodu ekleyerek.
Çağlar, IE9 + ve Presto-Opera 12'den itibaren makul tarayıcılarla çalışır.

<!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>

Not: İkinci bir isteğin üstbilgilerini alırsınız, sonuç ilk istekten farklı olabilir.


Diğer bir yolu
daha modern fetch()API
https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch
Başına caniuse.com o Firefox 40, Chrome 42, Kenar 14, Safari 11 tarafından desteklenen
Çalışma örneği kod:

<!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>

0

Bu eski bir soru. Emin değilim destek daha geniş oldu ama ne zaman getAllResponseHeaders()ve getResponseHeader()şimdi oldukça standart olarak görünmektedir: http://www.w3schools.com/xml/dom_http.asp


50
getAllResponseHeaders () ve getResponseHeader (), XMLHttpRequest nesnesinin yöntemleridir. Yani ajax istekleri için. İlk sayfanın üstbilgilerini görüntülemek için bu yöntemleri kullanamazsınız - orijinal sorunun gerçekten sorduğunu düşünüyorum.
asgeo1

-1

Daha önce de belirtildiği gibi, sunucu tarafını kontrol ederseniz, ilk istek başlıklarını ilk yanıtta istemciye geri göndermek mümkün olmalıdır.

Örneğin, Express'te aşağıdakiler çalışır:

app.get('/somepage', (req, res) => { res.render('somepage.hbs', {headers: req.headers}); }) Başlıklar şablon içinde kullanılabilir, bu nedenle görsel olarak gizlenebilir, ancak işaretlemeye dahil edilebilir ve clientide javascript tarafından okunabilir.


Soru, üstbilgi istemek değil, yanıt üstbilgilerini sormaktır.
Quentin

-1

Sorunun yanlış gittiğini düşünüyorum, İstek başlığını JQuery / JavaScript'ten almak istiyorsanız, cevap basittir. Aspx sayfasındaki tüm istekleri alın ve bir oturum / çerezler koyun, ardından JavaScript sayfasındaki çerezlere erişebilirsiniz.


1
Soru, yanıt başlıklarını okumaktır . Talep başlıklarından sadece olası soru bağlamında bahsedilir.
Quentin
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.