JQuery Ajax-a zəng etdikdən sonra bir yönlendirme sorğusunu idarə etmək

Ajax istifadə edərək $.post() zəng etmək üçün $.post() istifadə edin və nəticədə yaranan HTML fraqmentini cari istifadəçi səhifəsində div elementini əvəz etmək üçün istifadə edin. Lakin, sessiya başa çatdıqda, server istifadəçi giriş səhifəsinə göndərmək üçün bir yönlendirme yönergesi göndərir. Bu halda, jQuery, giriş səhifəsinin məzmunu ilə div elementini əvəz edir, istifadəçinin gözləri nadir görünüşü görməyə səbəb olur.

JQuery 1.2.6 istifadə edərək Ajax zəngindən yönlendirme təlimatını necə idarə edə bilərəm?

1175
14 окт. 14 oktyabrda Elliot Vargas tərəfindən təyin olundu 2008-10-14 00:29 '08 də 0:29 2008-10-14 00:29
ответ 31 cavab
  • 1
  • 2

Sonda tətbiq olunan həll, Ajax geri çağırma funksiyası üçün sargıdan istifadə etmək və geri qaytarılmış HTML blokunda müəyyən bir elementin mövcudluğu üçün bu qanaddan istifadə etmək idi. Bir maddə tapılsa, qabıq yenidən yönəldilir. Əks halda, banderol zəngləri faktiki geri çağırma funksiyasına yönləndirdi.

Örneğin, paketleme funksiyası belə bir şeydi:

 function cbWrapper(data, funct){ if($("#myForm", data).length > 0) top.location.href="login.htm";//redirection else funct(data); } 

Sonra bir Ajax zəngini yaratarkən, biz aşağıdakı kimi bir şey istifadə etdik:

 $.post("myAjaxHandler", { param1: foo, param2: bar }, function(data){ cbWrapper(data, myActualCB); }, "html" ); 

Bu, bizim üçün işləmişdir, çünki bütün Ajax zəngləri həmişə HTML-i DIV elementinin içərisinə qaytarır və biz səhifənin bir hissəsini əvəz etmək üçün istifadə edirik. Bundan əlavə, giriş səhifəsinə yönləndirmək məcburiyyətindəyik.

85
27 янв. Elliot Vargas 27 Yanvar cavablandırdı 2009-01-27 21:10 '09 9:10 pm 2009-01-27 21:10

Mən bu soruyu oxumuşdum və yönlendirme zamanı brauzer şəffaflığından qaçınmaq üçün cavab status kodunu 278-ə təyin etmək üçün hazırlanmış yanaşmanı həyata keçirdim. Bu işlə məşğul olmasına baxmayaraq, bir az hacked, çünki mən bir az bədbəxt idi.

Qazmağa başladıqdan sonra bu yanaşma atdı və JSON istifadə etdi. Bu halda, ajax sorğularına verilən bütün cavablar status koduna malikdir və cavab orqanında server üzərində qurulmuş bir JSON obyekti var. Sonra müştəri üzərində javascript JSON obyektindən istifadə etmək üçün nə etmək lazım olduğuna qərar verə bilər.

Sizinlə oxşar bir problemim var idi. 2 ehtimal cavab verən bir ajax sorğusunu işə salıram: brauzerin yeni bir səhifəyə yönəldiyi və cari səhifədəki mövcud HTML formasını yenisi ilə əvəz edən bir. Bunun üçün jquery kodu aşağıdakı kimi görünür:

border=0
 $.ajax({ type: "POST", url: reqUrl, data: reqBody, dataType: "json", success: function(data, textStatus) { if (data.redirect) { // data.redirect contains the string URL to redirect to window.location.href = data.redirect; } else { // data.form contains the HTML for the replacement form $("#myform").replaceWith(data.form); } } }); 

JSON obyektinin obyekt məlumatları serverdə 2 üzvə malikdir: data.redirect və data.form. Mən bu yanaşmayı daha yaxşı tapdım.

630
08 окт. Cavab verilir Steg 08 oktyabr. 2009-10-08 01:54 '09 at 1:54 'da 2009-10-08 01:54

Bu problemi həll etdim:

  • Cavab üçün xüsusi bir başlıq əlavə etmək:

     public ActionResult Index(){ if (!HttpContext.User.Identity.IsAuthenticated) { HttpContext.Response.AddHeader("REQUIRES_AUTH","1"); } return View(); } 
  • Javascript funksiyasını ajaxSuccess hadisə ilə ajaxSuccess və mövcud bir başlığı yoxlayın:

     $(document).ajaxSuccess(function(event, request, settings) { if (request.getResponseHeader('REQUIRES_AUTH') === '1') { window.location = '/'; } }); 
209
24 февр. cavab SuperG 24 fevralda verilir 2009-02-24 02:49 '09 at 2:49 pm 2009-02-24 02:49

Heç bir brauzer 301 və 302 cavabı düzgün idarə edə bilməz. Əslində, standart belə ki, onlar "şəffaf", onlar Ajax kitabxana satıcıları üçün MASSIVE baş ağrısı idarə etmək lazımdır ki, deyir. Ra-Ajax'da serverdən şəffaf şəkildə yönləndirmək üçün HTTP 278 cavab status kodunu (yalnız bəzi "istifadə edilməmiş" müvəffəqiyyət kodunu) istifadə etmək məcburiyyətindəyik ...

Bu, həqiqətən, məni narahat edir və əgər kiminsə W3C-də "çəkmək" olarsa, mən sizə təşəkkür edirəm ki, W3C-lə həqiqətən 301 və 302 kodlarını idarə etməliyik.

106
20 нояб. Thomas Hansen tərəfindən verilmiş cavab 20 noyabr 2008-11-20 11:39 '08 at 11:39 2008-11-20 11:39

Limmer bir az bükülü Timmer metodunu sevirəm. Mətn / htmldən contentType -i qaytarırsan, JSON- dan gözlədiyiniz zaman, çox güman ki, yenidən yönlendirileceksiniz. Mənim vəziyyətimdə sadəcə səhifəni yenidən yükləmək və giriş səhifəsinə yönəltdim. Oh, və dövlət jqXHR ki, səhv görünən 200 olduğunu yoxlamaq, çünki səhv funksiyası var, sağ? Əks təqdirdə tolerable səhvlər yenidən başladın (oops)

 $.ajax( error: function (jqXHR, timeout, message) { var contentType = jqXHR.getResponseHeader("Content-Type"); if (jqXHR.status === 200  contentType.toLowerCase().indexOf("text/html") >= 0) { // assume that our login has expired - reload our current page window.location.reload(); } }); 
56
23 авг. Cavab BrianY 23 avqustda verilir . 2011-08-23 22:21 '11 at 10:21 pm 2011-08-23 22:21

Aşağı səviyyəli $.ajax() zəngindən istifadə edin:

 $.ajax({ url: "/yourservlet", data: { }, complete: function(xmlHttp) { // xmlHttp is a XMLHttpRquest object alert(xmlHttp.status); } }); 

Bunu yönləndirmək üçün cəhd edin:

 if (xmlHttp.code != 200) { top.location.href = '/some/other/page'; } 
44
14 окт. Cavab 14 oktyabr qədər verilir . 2008-10-14 00:54 '08 at 0:54 2008-10-14 00:54

Yalnız bir yanaşmamı istəmişdim, çünki kimsə kömək edə bilər:

Mən əsasən bir istifadəçi adı göstərən kimi giriş nöqtəsinə redaksiya işləyən bu halda, identifikasiyası elementlərini işləyən JavaScript modulu daxil etmişəm.

Mənim ssenarimiz: əsasən, bütün sorğuların dinlənildiyi bir ISA server var və 302 və giriş səhifəmizin yerləşdiyi başlıq cavablandırılır .

Mənim javascript modulumda mənim ilk yanaşma bir şey idi

 $(document).ajaxComplete(function(e, xhr, settings){ if(xhr.status === 302){ //check for location header and redirect... } }); 

Problem (yuxarıda göstərildiyi kimi) brauzerin redirectionun özünü idarə ajaxComplete , buna görə də geri çağırma ajaxComplete heç vaxt çağırılmamışdır, amma bunun əvəzinə status 200status 200 olan açıq redaktə edilmiş giriş səhifəsinə bir cavab aldım. Problem: müvəffəqiyyətli bir cavabın 200 faktiki giriş səhifəsi və ya başqa bir rasgele səhifəsidir.

Həll

Mən cavabları 302 istiqamətləndirə LoginPage giriş səhifəsinin özü olan giriş LoginPage başlığını əlavə etdim. Modulda mən artıq başlığı dinləyərək yenidən yönləndirirəm:

 if(xhr.status === 200){ var loginPageRedirectHeader = xhr.getResponseHeader("LoginPage"); if(loginPageRedirectHeader  loginPageRedirectHeader !== ""){ window.location.replace(loginPageRedirectHeader); } } 

... və cazibədarlıq kimi işləyir :). xhr obyektindən bir yeri avtomatik redirection nəticəsində GET URL müəyyən etmək üçün bir yol tapa bilməmişəm, əsasən, LoginPage başlığında url daxil niyə merak edə bilər ...

31
23 мая '12 в 13:02 2012-05-23 13:02 Cavab 23 may 2012-ci il saat 13: 00-da Juri tərəfindən verilir. 2012-05-23 13:02

Mən bu mövzunun köhnə olduğunu bilirəm, ancaq burada və daha əvvəl təsvir etdiyim bir yanaşma verəcəyəm. Mən əsasən WIF ilə ASP.MVC istifadə edirəm (ancaq bu, bu mövzunun konteksti üçün çox vacib deyildir - cavab hansı çərçivədən istifadə olunarsa asılı olmayaraq kifayətdir.) Göstərici eynidır - ajax istəklərini yerinə yetirərkən identifikasiya səhvləri ilə bağlı problemləri həll edir).

Aşağıda göstərilən yanaşma, bütün ajax istəklərinə qutudan çıxarıla bilər (sendSend hadisə açıq şəkildə əks etdirmədikdə).

 $.ajaxSetup({ beforeSend: checkPulse, error: function (XMLHttpRequest, textStatus, errorThrown) { document.open(); document.write(XMLHttpRequest.responseText); document.close(); } }); 

Hər hansı bir ajax tələbi CheckPulse əvvəl CheckPulse metodu (hər hansı bir sadə ola bilən nəzarətçi üsulu) deyilir:

 [Authorize] public virtual void CheckPulse() {} 

İstifadəçi təsdiqlənməyibsə (token sona çatdı), bu metoddan istifadə edilə bilməz ( Authorize xüsusiyyətiylə qorunur). Təminat identifikasiyası prosesini işlədiyindən və mö'cüzənin müddəti başa çatdıqdan sonra, cavab olaraq HTTP statusu 302 göndərir. Brauzerinizin 302 cavabını şəffaf şəkildə idarə etməsini istəmirsinizsə, onu Global.asax-da tutun və reaksiya vəziyyətini dəyişdirin - məsələn, 200 OK. Bundan əlavə, bu cavabı xüsusi şəkildə (sonradan müştəri tərəfində) işləməyi sizə göstərib bir başlıq əlavə edin:

 protected void Application_EndRequest() { if (Context.Response.StatusCode == 302  (new HttpContextWrapper(Context)).Request.IsAjaxRequest()) { Context.Response.StatusCode = 200; Context.Response.AddHeader("REQUIRES_AUTH", "1"); } } 

Nəhayət, müştəri tərəfində belə bir xüsusi başlığa baxın. Əgər varsa, giriş səhifəsinə tam şəkildə window.location (mənim vəziyyətimdə window.location , mənim çərçivəmə tərəfindən avtomatik olaraq işlənilən window.location URL ilə əvəzlənir).

 function checkPulse(XMLHttpRequest) { var location = window.location.href; $.ajax({ url: "/Controller/CheckPulse", type: 'GET', async: false, beforeSend: null, success: function (result, textStatus, xhr) { if (xhr.getResponseHeader('REQUIRES_AUTH') === '1') { XMLHttpRequest.abort(); // terminate further ajax execution window.location = location; } } }); } 
26
07 мая '13 в 2:55 2013-05-07 02:55 Cavab 07 may 2013- cü il saat 2:55 radələrində jwaliszko tərəfindən verilmişdir 2013-05-07 02:55

Hesab edirəm ki, bunun əvəzinin ən yaxşı yolu mövcud HTTP protokolu cavab kodlarını, xüsusən 401 Unauthorized istifadə etməkdir.

Bunu necə qərar verdim:

  • Server tərəfi: sessiya başa çatdıqda və sorğu - ajax. cavab kodu başlığını 401 göndərin
  • Müştəri tərəfi: ajax hadisələrinə məcburdur

     $('body').bind('ajaxSuccess',function(event,request,settings){ if (401 == request.status){ window.location = '/users/login'; } }).bind('ajaxError',function(event,request,settings){ if (401 == request.status){ window.location = '/users/login'; } }); 

IMO daha ümumidir və hər hansı yeni istifadəçi spec / başlığı yazmırsınız. Ayrıca mövcud ajax zənglərini dəyişdirməyinizə də ehtiyac yoxdur.

Düzenle: Aşağıdakı @Rob şərhində, 401 (təsdiqləmə səhvləri üçün HTTP status kodu) bir göstərici olmalıdır. Daha ətraflı məlumat üçün 403 Yasaklı və 401 icazəsiz HTTP Cavablar baxın. Buna baxmayaraq, bəzi web çərçivələrində kimlik doğrulama və yetkilendirme səhvləri üçün 403 istifadə olunur, buna görə uyğunlaşdırın. Təşəkkürlər Rob.

21
23 окт. 23 aylıq rinop cavab verildi . 2012-10-23 19:27 '12 at 7:27 pm 2012-10-23 19:27

Bu problemi aşağıdakı kimi həll etdim:

Cavabın idarə olunması üçün ara proqram əlavə etsəniz, bu ajax sorğusu üçün yenidən yönlendiriliyorsa, yönlendirme URL'si ilə normal bir cavabın cavabı dəyişdirin.

 class AjaxRedirect(object): def process_response(self, request, response): if request.is_ajax(): if type(response) == HttpResponseRedirect: r = HttpResponse(json.dumps({'redirect': response['Location']})) return r return response 

Sonra ajaxComplete, cavab bir yönlendirme ehtiva edirsə, yenidən yönlendirilmeli, brauzerin yerini dəyişdirin.

 $('body').ajaxComplete(function (e, xhr, settings) { if (xhr.status == 200) { var redirect = null; try { redirect = $.parseJSON(xhr.responseText).redirect; if (redirect) { window.location.href = redirect.replace(/\?.*$/, "?next=" + window.location.pathname); } } catch (e) { return; } } } 
17
06 янв. Cavab Tyr Jan 06 tərəfindən verilir 2012-01-06 04:33 '12 at 4:33 2012-01-06 04:33

Mən tapdığım başqa bir həll (xüsusilə qlobal davranışı təyin etmək istəyirsinizsə faydalıdır) $.ajaxsetup() ilə birlikdə $.ajaxsetup() metodundan istifadə statusCode . Digərləri qeyd etdiyimiz kimi, redirection status code ( 3xx ) istifadə etməyin, 3xx status kodunu istifadə edin və redirection müştəri hissəsini 4xx .

 $.ajaxSetup({ statusCode : { 400 : function () { window.location = "/"; } } }); 

Əvəz etmək istədiyiniz status koduyla 400 əvəz edin. Daha əvvəl qeyd edildiyi kimi, 401 Unauthorized yaxşı bir fikir ola bilər. 400 istifadə edirəm, çünki çox qeyri-spesifikdir və daha konkret hallar üçün (məsələn, yanlış etimadnamələr) 401 istifadə edə bilərəm. Buna görə, birbaşa yönləndirməyin əvəzinə, 4xx və yenidən yönləndirmənin müştəri hissəsini 4xx backend 4xx səhv kodunu qaytarmalıdır. Hətta backbone.js kimi çərçivələrlə mənim üçün mükəmməl işləyir

17
02 мая '14 в 0:42 2014-05-02 00:42 Cavab verilir morten.c 02 May '14 at 0:42 2014-05-02 00:42

Bu məsələ ASP.NET MVC RedirectToAction metodundan istifadə edərkən baş verə bilər. Forma bir divdə görünməsini qarşısını almaq üçün, $ cavablarını daxil etmək üçün sadəcə bir növ ajax cavab filtresini edə bilərsiniz . AjaxSetup . Cavab MVC yönləndirməsini ehtiva edirsə, bu ifadəni JS tərəfində qiymətləndirə bilərsiniz. JS üçün nümunə kodu:

 $.ajaxSetup({ dataFilter: function (data, type) { if (data  typeof data == "string") { if (data.indexOf('window.location') > -1) { eval(data); } } return data; } }); 

Əgər məlumat: "window.location =" / Acount / Login "filtrin üstündə olsaydı və çıxışa icazə verməyincə, onu yönləndirməyə qiymətləndirər.

17
27 окт. Cavab 27 oktyabrda Przemek Marcinkiewicz tərəfindən verilir . 2016-10-27 16:31 '16 'da saat 16:31 ' da 2016-10-27 16:31 'də

Yuxarıda göstərilən həllərin əksəriyyəti əlavə bir başlıq və ya qeyri-adekvat HTTP kodu istifadə edərək, bir müddətdən istifadə edir. Bu həllər çox güman ki işləyəcək, amma bir az "hack". Başqa bir həll ilə gəldim.

Biz 401 reaksiyasına yönəldilən (passiveRedirectEnabled = "true") yönləndirilmiş WIF-dən istifadə edirik. Nöqtələrin istifadəsi müntəzəm istəklərdən istifadə edərkən faydalıdır, lakin AJAX sorğuları üçün işləməyəcəkdir (brauzerlər 302 / təkrar istiqamətləndirməyəcəklər).

Global.asax-da aşağıdakı kodu istifadə edərək, AJAX tələblərinə yönləndirməni aradan buraxa bilərsiniz:

  void WSFederationAuthenticationModule_AuthorizationFailed(object sender, AuthorizationFailedEventArgs e) { string requestedWithHeader = HttpContext.Current.Request.Headers["X-Requested-With"]; if (!string.IsNullOrEmpty(requestedWithHeader)  requestedWithHeader.Equals("XMLHttpRequest", StringComparison.OrdinalIgnoreCase)) { e.RedirectToIdentityProvider = false; } } 

Bu, AJAX sorğularında, javascript səhifənin yenidən yüklənməsi ilə idarə oluna biləcək 401 cavabı qaytarmağa imkan verir. Bir səhifənin yenidən yüklənməsi WIF tərəfindən işlənəcək 401-i çağırır (və WIF istifadəçi giriş səhifəsinə yönləndirəcək).

401 səhvin idarə olunması üçün nümunə javascript:

 $(document).ajaxError(function (event, jqxhr, settings, exception) { if (jqxhr.status == 401) { //Forbidden, go to login //Use a reload, WIF will redirect to Login location.reload(true); } }); 
16
14 февр. Cavab 14 fevralda Rob tərəfindən verildi . 2014-02-14 16:56 '14 saat 16:56 2014-02-14 16:56

Vladimir Prudnikov və Tomas Hansenin dediklərini birləşdirərək:

  • XHR olduğunu müəyyən etmək üçün server kodunuzu dəyişdirin. Əgər belədirsə, redaktə cavab kodunu 278 nömrəsinə qoyun. Yanğın zamanı:
  if request.is_ajax(): response.status_code = 278 

Bu, brauzerin cavabı uğur olaraq qəbul etməsinə və Javascript-a ötürülməsinə səbəb olur.

  • JS-də, forma Ajax vasitəsilə təqdim olunduğundan əmin olun, cavab kodunu yoxlayın və lazım olduqda yönləndirin:
 $('#my-form').submit(function(event){ event.preventDefault(); var options = { url: $(this).attr('action'), type: 'POST', complete: function(response, textStatus) { if (response.status == 278) { window.location = response.getResponseHeader('Location') } else { ... your code here ... } }, data: $(this).serialize(), }; $.ajax(options); }); 
15
06 авг. Cavab Graham King 06 aug tərəfindən verilir . 2009-08-06 23:17 '09 at 23:17 2009-08-06 23:17

Mənim üçün işləyən sadə bir həll var, server kodunu əvəz etməməyə ehtiyac yoxdur ...

 $(document).ready(function () { $(document).ajaxSend( function(event,request,settings) { var intercepted_success = settings.success; settings.success = function( a, b, c ) { if( request.responseText.indexOf( "<html>" ) > -1 ) window.location = window.location; else intercepted_success( a, b, c ); }; }); }); 

Html etiketinin varlığını yoxlayıram, ancaq giriş səhifənizdə hər hansı bir simli axtarış etmək üçün indexOf dəyişə bilərsiniz ...

14
17 авг. Timmerz tərəfindən verilmiş cavab 17 av . 2010-08-17 21:07 '10 at 21:07 2010-08-17 21:07

Keçir

  $(document).ready(function () { if ($("#site").length > 0) { window.location = "<%= Url.Content("~") %>" + "Login/LogOn"; } }); 

Giriş səhifəsinə yerləşdirin. Əsas səhifədə bir divə yüklənmiş olsaydı, giriş səhifəsinə yönəldiləcəkdir. "#site" giriş səhifəsi istisna olmaqla, bütün səhifələrdə olan bir div identifikatorudur.

11
05 окт. cavab 05 oktyabr tarixinə verilir . 2010-10-05 09:53 '10 at 9:53 2010-10-05 09:53
  <script> function showValues() { var str = $("form").serialize(); $.post('loginUser.html', str, function(responseText, responseStatus, responseXML){ if(responseStatus=="success"){ window.location= "adminIndex.html"; } }); } </script> 
11
10 сент. Cavab Priyanka 10 sep verilir . 2011-09-10 19:44 '11 saat 19:44 'da 2011-09-10 19:44

Mən bunu login.php səhifəsinə daxil etməklə həll etdim.

 <script type="text/javascript"> if (top.location.href.indexOf('login.php') == -1) { top.location.href = '/login.php'; } </script> 
10
05 дек. Paul Richards tərəfindən verilmiş cavab 05 dekabr 2011-12-05 22:59 '11 saat 10:59 'da 2011-12-05 22:59

Bahar Təhlükəsizliyi istifadə edərkən cavablar insanlara işarə edirsə də, LoginUrlAuthenticationEntryPoint uzadılmasını və AJAX-ı daha yaxşı idarə etmək üçün bəzi kodları əlavə edirəm. Çox nümunə yalnız təkrarlama uğursuzluqları deyil, bütün istiqamətlərə yönəldir. Bunun üzərində çalışdığım layihə üçün arzuolunmazdı. Failed AJAX tələbinin önbelleğe alınmasını istəmirsinizsə də, ExceptionTranslationFilter-i genişləndirmək və caching addımını aradan qaldırılması üçün sendStartAuthentication metodunu ləğv etmək lazımdır.

Məsələn AjaxAwareAuthenticationEntryPoint:

 public class AjaxAwareAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint { public AjaxAwareAuthenticationEntryPoint(String loginUrl) { super(loginUrl); } @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { if (isAjax(request)) { response.sendError(HttpStatus.UNAUTHORIZED.value(), "Please re-authenticate yourself"); } else { super.commence(request, response, authException); } } public static boolean isAjax(HttpServletRequest request) { return request != null  "XMLHttpRequest".equals(request.getHeader("X-Requested-With")); } } 

Mənbələr: 1 , 2

9
17 сент. Cavab 17 sentyabrda Yəhya tərəfindən verilir . 2013-09-17 19:07 '13 at 07:07 pm 2013-09-17 19:07

Bəziləri faydalı ola bilər:

Müştərilərə bir icazə etmə olmadan göndərilən istənilən bir istirahət üçün giriş səhifəsinə yönləndirilməsini istədi. Mənim bütün istirahət fəaliyyətləri Ajax-a əsaslanan olduğundan, Ajax müvəffəqiyyət funksiyasını yerinə yetirmək əvəzinə giriş səhifəsinə yönəltmək üçün yaxşı ümumi bir yola ehtiyacım var.

Mən bunu etdi:

Hər hansı bir Ajax xahişi ilə, serverim Json 200 cavabını "QEYDİYYAT İSTƏYİR" (müştərinin kimliyə ehtiyacı olduğu təqdirdə) qaytaracaq.

Java-da sadə bir nümunə (server tərəfində):

 @Secured @Provider @Priority(Priorities.AUTHENTICATION) public class AuthenticationFilter implements ContainerRequestFilter { private final Logger m_logger = LoggerFactory.getLogger(AuthenticationFilter.class); public static final String COOKIE_NAME = "token_cookie"; @Override public void filter(ContainerRequestContext context) throws IOException { // Check if it has a cookie. try { Map<String, Cookie> cookies = context.getCookies(); if (!cookies.containsKey(COOKIE_NAME)) { m_logger.debug("No cookie set - redirect to login page"); throw new AuthenticationException(); } } catch (AuthenticationException e) { context.abortWith(Response.ok("\"NEED TO AUTHENTICATE\"").type("json/application").build()); } } } 

Mənim javascriptimdə aşağıdakı kodu əlavə etmişəm:

 $.ajaxPrefilter(function(options, originalOptions, jqXHR) { var originalSuccess = options.success; options.success = function(data) { if (data == "NEED TO AUTHENTICATE") { window.location.replace("/login.html"); } else { originalSuccess(data); } }; }); 

Və nə haqqında.

7
09 апр. Cavab Tomer 09 apr verilir . 2016-04-09 02:26 '16 at 2:26 pm 2016-04-09 02:26

Mən bütün səhifənin hər hansı bir ajax istəklərinə daxil olmaq istədim. @SuperG mənə başlamışdır. Budur bitirdiğim şey:

 // redirect ajax requests that are redirected, not found (404), or forbidden (403.) $('body').bind('ajaxComplete', function(event,request,settings){ switch(request.status) { case 301: case 404: case 403: window.location.replace("http://mysite.tld/login"); break; } }); 

Mən qərarımı haqq qazandırmaq üçün müəyyən http statusu kodlarını xüsusi olaraq yoxlamaq istəmişdim. Lakin, yalnız ajaxError-dən başqa bir şeyə (bəlkə yalnız 200) bənzəyirsiniz? Mən yalnız yaza bilərəm:

 $('body').bind('ajaxError', function(event,request,settings){ window.location.replace("http://mysite.tld/login"); } 
5
04 авг. Cavab Bretticus 04 aug tərəfindən verilir . 2010-08-04 21:47 '10 at 21:47 2010-08-04 21:47

Nəhayət, xüsusi HTTP Header əlavə edərək problemi həll edəcəyəm. Server tərəfindəki hər bir sorğunun cavabından əvvəl cavab başlığına daxil olan mövcud url əlavə edim.

Mənim Asp.Net MVC serverindədir və bunun üçün yaxşı bir yer var. Global.asax Application_EndRequest hadisəsini həyata Global.asax , buna görə:

  public class MvcApplication : System.Web.HttpApplication { // ... // ... protected void Application_EndRequest(object sender, EventArgs e) { var app = (HttpApplication)sender; app.Context.Response.Headers.Add("CurrentUrl",app.Context. Request.CurrentExecutionFilePath); } } 

Mənim üçün böyük işləyir! İndi hər bir JQuery $.post cavabında 302 , 303 , statusu üzrə POST metodunun nəticəsidir ki, istənilən url , eləcə də digər cavab başlıqları var ....

digərinə isə kodun server tərəfində və ya müştəri tərəfində dəyişdirilməsinə ehtiyac yoxdur.

а следующая - возможность получить доступ к другой информации post post, такие ошибки, сообщения и... Таким образом.

Я разместил это, возможно, помогу кому-то:)

5
ответ дан Ali Adlavaran 30 июля '15 в 9:02 2015-07-30 09:02

У меня не было никакого успеха в решении заголовка - они никогда не поднимались в моем методе ajaxSuccess/ajaxComplete. Я использовал ответ Steg с пользовательским ответом, но я немного изменил сторону JS. Я настраиваю метод, который я вызываю в каждой функции, поэтому я могу использовать стандартные методы $.get и $.post .

 function handleAjaxResponse(data, callback) { //Try to convert and parse object try { if (jQuery.type(data) === "string") { data = jQuery.parseJSON(data); } if (data.error) { if (data.error == 'login') { window.location.reload(); return; } else if (data.error.length > 0) { alert(data.error); return; } } } catch(ex) { } if (callback) { callback(data); } } 

Пример использования...

 function submitAjaxForm(form, url, action) { //Lock form form.find('.ajax-submit').hide(); form.find('.loader').show(); $.post(url, form.serialize(), function (d) { //Unlock form form.find('.ajax-submit').show(); form.find('.loader').hide(); handleAjaxResponse(d, function (data) { // ... more code for if auth passes ... }); }); return false; } 
5
ответ дан jocull 06 февр. '13 в 16:45 2013-02-06 16:45

Если вы также хотите передать значения, вы также можете установить переменные сеанса и получить доступ Например: В вашем jsp вы можете написать

 <% HttpSession ses = request.getSession(true); String temp=request.getAttribute("what_you_defined"); %> 

И затем вы можете сохранить это значение темпа в своей переменной javascript и поиграть

5
ответ дан karthik339 07 янв. '13 в 9:35 2013-01-07 09:35

в сервлете, который вы должны положить response.setStatus(response.SC_MOVED_PERMANENTLY); для отправки статуса "301" xmlHttp, необходимого для перенаправления...

а в функции $.ajax вы не должны использовать функцию .toString() ..., просто

if (xmlHttp.status == 301) { top.location.href = 'xxxx.jsp'; }

проблема в том, что она не очень гибкая, вы не можете решить, куда вы хотите перенаправить.

перенаправление через сервлеты должно быть наилучшим способом. но я все еще не могу найти правильный способ сделать это.

5
ответ дан Juan Toro 14 нояб. '08 в 23:56 2008-11-14 23:56

Вы также можете подключить прототип отправки XMLHttpRequest. Это будет работать для всех отправок (jQuery/ dojo/etc) с помощью одного обработчика.

Я написал этот код для обработки ошибки на 500 страниц с истекшим сроком действия, но он должен работать так же хорошо, как ловушка перенаправления 200. Готов к записи wikipedia на XMLHttpRequest onreadystatechange о значении readyState.

 // Hook XMLHttpRequest var oldXMLHttpRequestSend = XMLHttpRequest.prototype.send; XMLHttpRequest.prototype.send = function() { //console.dir( this ); this.onreadystatechange = function() { if (this.readyState == 4  this.status == 500  this.responseText.indexOf("Expired") != -1) { try { document.documentElement.innerHTML = this.responseText; } catch(error) { // IE makes document.documentElement read only document.body.innerHTML = this.responseText; } } }; oldXMLHttpRequestSend.apply(this, arguments); } 
4
ответ дан Curtis Yallop 10 апр. '12 в 22:38 2012-04-10 22:38

У меня была эта проблема в приложении django, с которым я возился (отказ от ответственности: я возился, чтобы учиться, и я никоим образом не специалист). То, что я хотел сделать, это использовать jQuery ajax для отправки запроса DELETE на ресурс, удалить его на стороне сервера, а затем отправить перенаправление обратно (в основном) на главную страницу. Когда я отправил HttpResponseRedirect('/the-redirect/') из python script, метод jQuery ajax получал 200 вместо 302. Итак, я сделал, чтобы отправить ответ 300 с помощью:

 response = HttpResponse(status='300') response['Location'] = '/the-redirect/' return response 

Затем я отправил/обработал запрос на клиенте с помощью jQuery.ajax следующим образом:

 <button onclick="*the-jquery*">Delete</button> where *the-jquery* = $.ajax({ type: 'DELETE', url: '/resource-url/', complete: function(jqxhr){ window.location = jqxhr.getResponseHeader('Location'); } }); 

Возможно, использование 300 не является "правильным", но, по крайней мере, оно работает так, как я этого хотел.

PS: это была огромная боль для редактирования на мобильной версии SO. Глупый интернет-провайдер подал запрос на отмену моего обслуживания, когда я закончил с моим ответом!

4
ответ дан Benny Jobigan 28 авг. '11 в 13:18 2011-08-28 13:18

Кроме того, вы, вероятно, захотите перенаправить пользователя к указанному в URL-адресе заголовков. Итак, это будет выглядеть так:

 $.ajax({ //.... other definition complete:function(xmlHttp){ if(xmlHttp.status.toString()[0]=='3'){ top.location.href = xmlHttp.getResponseHeader('Location'); } }); 

UPD: Opps. Иметь ту же задачу, но она не работает. Делать это. Я покажу вам решение, когда найду его.

1
ответ дан Vladimir Prudnikov 19 окт. '08 в 13:14 2008-10-19 13:14

Позвольте мне просто повторить проблему, описанную @Steg

У меня была схожая проблема с твоей. Я выполняю запрос ajax, который имеет 2 возможных ответа: один, который перенаправляет браузер на новую страницу и заменяет существующую HTML-форму на текущей странице новой.

IMHO - это настоящая проблема, и ее необходимо будет официально распространить на существующие HTTP-стандарты.

Я считаю, что новый стандарт Http будет использовать новый код состояния. значение: в настоящее время 301/302 сообщает браузеру, чтобы он отправил содержимое этого запроса в новое location .

В расширенном стандарте он скажет, что если status: 308 ответа status: 308 (просто пример), браузер должен перенаправить главную страницу в указанное location .

Что, как говорится; Я склонен уже подражать этому будущему поведению, поэтому, когда необходим document.redirect, я отвечаю на сервер как:

 status: 204 No Content x-status: 308 Document Redirect x-location: /login.html 

Когда JS получает " status: 204 ", он проверяет наличие заголовка x-status: 308 и делает document.redirect на странице, представленной в заголовке location .

Это имеет какое-то значение для вас?

1
ответ дан Chaim Klar 13 июля '18 в 0:45 2018-07-13 00:45

У меня есть рабочий solulion, используя ответы от @John и @Arpad ссылка и @RobWinch ссылка

Я использую Spring Security 3.2.9 и jQuery 1.10.2.

Расширьте класс Spring, чтобы вызвать ответ 4XX только из запросов AJAX:

 public class CustomLoginUrlAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint { public CustomLoginUrlAuthenticationEntryPoint(final String loginFormUrl) { super(loginFormUrl); } // For AJAX requests for user that isn't logged in, need to return 403 status. // For normal requests, Spring does a (302) redirect to login.jsp which the browser handles normally. @Override public void commence(final HttpServletRequest request, final HttpServletResponse response, final AuthenticationException authException) throws IOException, ServletException { if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) { response.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied"); } else { super.commence(request, response, authException); } } } 

ApplicationContext-security.xml

  <security:http auto-config="false" use-expressions="true" entry-point-ref="customAuthEntryPoint" > <security:form-login login-page='/login.jsp' default-target-url='/index.jsp' authentication-failure-url="/login.jsp?error=true" /> <security:access-denied-handler error-page="/errorPage.jsp"/> <security:logout logout-success-url="/login.jsp?logout" /> ... <bean id="customAuthEntryPoint" class="com.myapp.utils.CustomLoginUrlAuthenticationEntryPoint" scope="singleton"> <constructor-arg value="/login.jsp" /> </bean> ... <bean id="requestCache" class="org.springframework.security.web.savedrequest.HttpSessionRequestCache"> <property name="requestMatcher"> <bean class="org.springframework.security.web.util.matcher.NegatedRequestMatcher"> <constructor-arg> <bean class="org.springframework.security.web.util.matcher.MediaTypeRequestMatcher"> <constructor-arg> <bean class="org.springframework.web.accept.HeaderContentNegotiationStrategy"/> </constructor-arg> <constructor-arg value="#{T(org.springframework.http.MediaType).APPLICATION_JSON}"/> <property name="useEquals" value="true"/> </bean> </constructor-arg> </bean> </property> </bean> 

В моих JSP добавьте глобальный обработчик ошибок AJAX, как показано здесь

  $( document ).ajaxError(function( event, jqxhr, settings, thrownError ) { if ( jqxhr.status === 403 ) { window.location = "login.jsp"; } else { if(thrownError != null) { alert(thrownError); } else { alert("error"); } } }); 

Также удалите существующие обработчики ошибок из вызовов AJAX в JSP-страницах:

  var str = $("#viewForm").serialize(); $.ajax({ url: "get_mongoDB_doc_versions.do", type: "post", data: str, cache: false, async: false, dataType: "json", success: function(data) { ... }, // error: function (jqXHR, textStatus, errorStr) { // if(textStatus != null) // alert(textStatus); // else if(errorStr != null) // alert(errorStr); // else // alert("error"); // } }); 

Я надеюсь, что это поможет другим.

Update1 Я обнаружил, что мне нужно добавить параметр (always-use-default-target = "true" ) в конфигурацию для входа в форму. Это было необходимо, так как после запроса AJAX перенаправляется на страницу входа (из-за истекшего сеанса), Spring запоминает предыдущий запрос AJAX и автоматически перенаправляет его после входа в систему. Это приведет к отображению возвращаемого JSON на странице браузера. Конечно, не то, что я хочу.

Update2 Вместо использования always-use-default-target="true" используйте пример @RobWinch для блокировки запросов AJAX из requstCache. Это позволяет нормальным ссылкам перенаправляться на исходную цель после входа в систему, но AJAX переходит на домашнюю страницу после входа в систему.

0
ответ дан Darren Parker 22 марта '18 в 0:17 2018-03-22 00:17
  • 1
  • 2

Другие вопросы по меткам или Задайте вопрос