JQuery kullanarak ajax isteklerinin yönlendirmeleri takip etmesini önleme


103

Bir web hizmetine erişmek için jQuery ajax işlevlerini kullanıyorum, ancak sunucu, bir sorunu açıklayan bir durum kodu içeren bir yanıt döndürmek yerine, istek sorunu açıklayan 200 başlıklı bir sayfaya yönlendiriliyor. Bunda herhangi bir değişiklik yapamıyorum, bu yüzden müşteride bir şekilde çözmem gerekiyor.

Örnek: Bir istek, bulunmayan bir URL'ye gidiyor, bu yüzden başka bir yere 302 Yönlendirmesi alıyorum. Yeni bir istek gönderildi ve 200 OK aldım, böylece hata geri aramasının başlamasını önledim.

Ajax isteğinin yönlendirmeleri takip etmesini ve bunun yerine bir geri aramayı, tercihen hata yöntemini çağırmasını engellememin bir yolu var mı? Alternatif olarak, istemcide bir yeniden yönlendirme olup olmadığını tespit etmek mümkün müdür?



8
Arka
ucunuzun

Yanıtlar:


96

Sorunuzu ilginç buluyorum, ancak genel olarak sorun bana daha çok bir yanlış anlama gibi görünüyor. En azından problemi anladığımı açıklamaya çalışacağım.

Sessiz (şeffaf) yönlendirme, XMLHttpRequestspesifikasyonun bir parçasıdır ( özellikle buraya bakın , "... yönlendirmeyi şeffaf bir şekilde takip edin ..." kelimeleri). Standart, yalnızca kullanıcı aracısının (web tarayıcısı) belirli türdeki otomatik yönlendirmeleri önleyebileceğini veya bildirebileceğini belirtir, ancak bunun bir parçası değildir XMLHttpRequest. HTTP istemci yapılandırmasının (işletim sistemi yapılandırması) veya web tarayıcısı yapılandırmasının bir parçasıdır. Dolayısıyla jQuery.ajax, yeniden yönlendirmeyi engelleyebileceğiniz herhangi bir seçeneğiniz olamaz.

HTTP yeniden yönlendirmesinin HTTP protokolünün bir parçası olduğunu ve bunun bir parçası olmadığını görebilirsiniz XMLHttpRequest. Yani, başka bir soyutlama seviyesinde veya ağ yığınında. Örneğin, içindeki veriler XMLHttpRequestHTTP proxy'den veya yerel tarayıcı önbelleğinden alınabilir ve bu, HTTP protokolünün bir parçasıdır. Çoğunlukla verileri sağlayan sunucu önbelleğe alma işlemini etkileyebilir.

Sorunuzdaki gereksinimi, web sunucusunun IP adresinin değiştirilmesini veya iletişim sırasında IP yolunun değiştirilmesini önleme gereksinimi ile karşılaştırabilirsiniz. Bazı senaryolarda her şey ilginç olabilir, ancak iletişim yığınının başka bir seviyesinin parçaları vardır ve jQuery.ajaxveya tarafından yönetilemez XMLHttpRequest.

XMLHttpRequestİstemci yapılandırma yönlendirmeyi önleyen seçeneklere sahip olabileceği standart diyelim. Daha iyi bildiğim "Microsoft dünyası" durumunda , değer ile seçeneği ayarlamak için kullanılabilecek WinHttpSetOption işlevine bakabilirsiniz . Başka bir yol da seçeneğin değeri ile kullanılmasıdır. Windows'ta kullanabileceğiniz bir başka özellik, geri arama işlevini ayarlayabilen WinHttpSetStatusCallback işlevidir .WINHTTP_OPTION_DISABLE_FEATUREWINHTTP_DISABLE_REDIRECTSWINHTTP_OPTION_REDIRECT_POLICYWINHTTP_OPTION_REDIRECT_POLICY_NEVERWINHTTP_CALLBACK_FLAG_REDIRECT

Dolayısıyla, gereksinimlerinizi genel olarak uygulamak mümkündür, ancak çözüm muhtemelen işletim sisteminden veya web tarayıcısından bağımsız olmayacak ve jQuery.ajaxveya düzeyinde olmayacaktır XMLHttpRequest.


2
Harika içgörüyle mükemmel yanıt! Curl ile ilgili bazı deneyimlerim var, bahsettiğiniz gibi benzer bayraklar koyabilirsiniz. Bu tür talimatların tarayıcıya iletilebileceğini umuyordum, ancak cevabınızdan, beklenen davranışın, ilk istek sunucu tarafından atanan konuma gönderilmiş gibi yönlendirmeleri takip etmek olacağını anlıyorum.
Jürgen

@ Jørgen: Hoş geldiniz! Çoğu senaryoda, yeniden yönlendirme hiç sorun teşkil etmez. JQuery.ajax'ı kullandığınız bağlamı ve isteği gönderdiğiniz web sunucusu üzerinde tam kontrole sahip olup olmadığınızı açıklamazsınız. Bu yüzden size probleminizi gerçekten çözebilecek başka tavsiyeler vermek zordur.
Oleg

Korkarım sunucu tarafını ben kontrol etmiyorum. Sanırım en iyi seçeneğim yanıt içeriğini analiz etmek veya doğrulamak.
Jürgen

@ Jørgen: Sizin durumunuzda yeniden yönlendirme neden bir sorun? Sunucu bir sayfayı geçici veya kalıcı olarak başka bir konuma taşıdıysa, orijinal isteğinizi yeni konuma yeniden yönlendirebilir. Kesinlikle iyi olacak. Bir yönetici, web sunucusunu, örneğin sunucudaki geri yükleme işlemi veya başka herhangi bir destek çalışması sırasında yeniden yönlendirme yapacak şekilde yapılandırabilir. Sunucuya DNS'ye sahip URL'yi sorarsanız, yönetici IP eşleştirmesini başka bir sunucuya değiştirebilir. DNS yeniden yapılandırması ile aynı şekilde HTTP yeniden yönlendirmesi yapabilir. Senin problemin ne?
Oleg

Benim sorunum, yönlendirmenin genel bir hata sayfasına gitmesidir. Sunucunun farklı bir şekilde kurulması gerektiğini biliyorum ama şimdilik bu duruma bir çözüm bulmam gerekecek.
Jørgen

23

Bunun mümkün olduğuna inanmıyorum. Temel kitaplık (XHR) yeni isteği şeffaf bir şekilde yapar. Bununla birlikte, bu durumlarda yaptığım şey (genellikle beni bir oturum açma sayfasına götüren bir oturum zaman aşımı türü anlaşma) geri özel bir yanıt başlığı göndermektir. Ayrıca, bu başlığın varlığını kontrol eden ve mevcut olduğunda uygun şekilde yanıt veren (örneğin, tüm sayfayı oturum açma ekranına yönlendiren) global bir ajax işleyicisi kurdum.

İlgileniyorsanız, işte o özel başlık için izlemem gereken jQuery kodu:

/* redirects main window when AJAX request indicates that the session has expired on the backend. */
function checkSession(event, xhr, ajaxOptions)
{
    if (xhr.readyState == 4)
    {
        if(xhr.getResponseHeader("Login-Screen") != null && xhr.getResponseHeader("Login-Screen").length)
        {
            window.location.href='sessionExpired.html'; //whatever
        }
    }
}

$(document).ajaxComplete(checkSession)

1
Teşekkürler, sanırım yanıtı analiz ederek benzer bir yaklaşıma razı olmak zorunda kalacağım.
Jürgen

11

Aramanızın yeniden yönlendirilip yönlendirilmediğini kontrol etmek için bir özellik buldum. Xhr.state (): Eğer "reddedilmiş" ise, o zaman bir yönlendirme gerçekleşmiştir.

Başarı geri araması örneği:

request.success(function(data, textStatus, xhr)
{
    if(xhr.state() == "resolved")
    {
        //no redirection
    }
    if(xhr.state() == "rejected")
    {
        //redirection
    }
});

Hata geri aramalı örnek:

request.error(function(xhr, textStatus)
{
    if (xhr.state() == "rejected")
    {
        //redirection
        location.href = "loginpage";
    } else
    {
        //some other error happened
        alert("error");
    }
});

1
Cevabınızdaki ipucu, işleri yoluna koymamıza gerçekten yardımcı oldu. Başkalarına yardımcı olacak notlar uğruna, WebSphere Portal'ın güvenliğini SiteMinder ile bütünleştirdik. Bir kaynak url'sine Ajax çağrılarına ihtiyaç duyan bir portletimiz var ve zaman aşımına uğradığında, şeffaf yeniden yönlendirmeler oluyor, ancak oturum açma sayfasına nasıl yeniden yönlendirileceğimizi hiçbir yerde çözemiyoruz. JqXHR.state () 'in "reddedildiğini" kontrol etmek kesinlikle yardımcı oldu. Tekrar çok teşekkürler.
Uresh Kuruhuri

Harika bir keşif, ancak yanlış pozitifler olabilir, çünkü bir söz sadece yönlendirmede değil, reddedilse bile "reddedildi" durumu tetiklenebilir. jQuery, "reddedildi" durumunun ne zaman gönderildiğini açıklar api.jquery.com/deferred.state
Nitin

1

Yanıt veren önceki kodlayıcıların içgörülü bilgeliğine muhtemelen ekleyemem, ancak başkalarının bilmek için yararlı bulabileceği özel bir durum ekleyeceğim.

SharePoint bağlamında bu 302 sessiz yönlendirmeye rastladım. Bir SharePoint alt sitesine ping atan bazı basit Javascript istemci kodum var ve eğer 200 HTTP yanıtı alırsa, aracılığıyla o siteye taşınıyor window.location. Başka bir şey alırsa, kullanıcıya sitenin bulunmadığına dair bir uyarı verir.

Ancak sitenin mevcut olduğu ancak kullanıcının izninin olmadığı durumda, SharePoint sessizce AccessDenied.aspx sayfasına yeniden yönlendirir. SharePoint, sunucu / grup düzeyinde HTTP 401 kimlik doğrulama anlaşmasını zaten gerçekleştirdi - kullanıcının SharePoint'e erişimi var. Ancak alt siteye erişim, sanırım bir tür veritabanı bayrakları kullanılarak gerçekleştiriliyor. Sessiz yeniden yönlendirme "else" cümlesimi atlar, bu yüzden kendi hatamı ortaya koyamam. Benim durumumda, bu bir şov durdurucu değil - tutarlı, tahmin edilebilir bir davranış. Ancak bu biraz şaşırtıcıydı ve bu süreçte HTTP istekleri hakkında bir şeyler öğrendim!


1

Ben de aynı şeyle ilgileniyordum ve Takman'ın bahsettiğistate() yöntemi bulamadım ve kendim için biraz kazı yaptım. Buraya bir cevap arayışına giren insanların iyiliği için, işte bulgularım:

Birçok kez belirtildiği gibi, yeniden yönlendirmeleri önleyemezsiniz, ancak onları tespit edebilirsiniz. MDN'ye göre , tüm yönlendirmelerden sonra yanıtın geldiği nihai URL'yi içerecek olan responseURLof 'i kullanabilirsiniz XMLHttpRequestObject. Yalnızca uyarı, Internet Explorer tarafından desteklenmemesidir (Edge'de vardır). Yana xhr/ jqXHRgeçirilen success/ donejquery fonksiyonu gerçek bir uzantısıdır XMLHttpRequest, o da orada mevcut olmalıdır.


0

Sanırım 200 yanıtı alıyorsunuz çünkü ikinci kez yönlendirme yok, 404 sayfasının süresi dolmadığı için önbellekte saklanıyor. Bu, tarayıcının size önbellekteki sayfayı ikinci kez verdiği anlamına gelir. Ajax jquery'de bir özellik "önbellek" vardır. http://api.jquery.com/jQuery.ajax/

Bunu "yanlış" olarak yazmalısın


0

XmlHttpRequests'de konum yönlendirmesini devre dışı bırakmak mümkün olmasa da, fetch () kullanılırken geçerlidir :

fetch('url', {redirect: manual});

Getirme, size yönlendirilen URL'nin ne olduğunu söylemez. Davranışı devre dışı bırakabilirsiniz, ancak "redirect: manual" kullanıcının yeniden yönlendirmeyi kendisinin işlemesine izin vermeyi amaçlamaz.
lcjury

-2

Bunun sizin durumunuzda geçerli olup olmayacağından emin değilim, ancak AJAX işlevinde belirli durum kodlarına yanıt vermek için kod yazabilirsiniz -

$.ajax({
    url: '/admin/secret/data',
    type: 'POST',
    contentType: 'application/json; charset=utf-8',
    statusCode: {
        200: function (data) {
            alert('302: Occurred');
            // Bind the JSON data to the UI
        },
        401: function (data) {
            alert('401: Occurred');
            // Handle the 401 error here.
        }
    }
});

9
Bunun geçerli olduğunu sanmıyorum çünkü OP arka planda gerçekleşen yeniden yönlendirme nedeniyle her zaman 200 durum kodu aldığını söyledi ..
Evet Barry

-4

Ajax talebi durumunda istek başlıklarında aşağıdakilere sahip olacaksınız

X-Requested-With    XMLHttpRequest

Sunucu tarafında bu kriter ile istekleri filtreleyebilirsiniz.


İsteği değil yanıtı kontrol etmek istedi (zaten kontrolü elinde tutuyor)
Evet Barry

Belki Gfox, 3xx'i döndüren ajax isteklerinin anlamsız olduğunu, bu tür bir isteği filtreleyip 403'ü döndürebileceğinizi öne sürdü. form kimlik doğrulaması gerektiren sayfalar sunan bir web siteniz olduğunda ve bu sayfalar da ajax aramaları yaptığında ve yetkilendirme mantığını tek bir yere koymak istiyorsanız, o zaman bana göre bu geçerli bir cevaptır.
maciejW
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.