Saya menggunakan $.post()
untuk memanggil servlet menggunakan Ajax dan kemudian menggunakan fragmen HTML yang dihasilkan untuk mengganti div
elemen di halaman saat ini pengguna. Namun, jika sesi habis, server mengirimkan arahan pengalihan untuk mengirim pengguna ke halaman login. Dalam hal ini, jQuery mengganti div
elemen dengan konten halaman login, memaksa mata pengguna untuk menyaksikan adegan langka.
Bagaimana saya bisa mengelola arahan redirect dari panggilan Ajax dengan jQuery 1.2.6?
javascript
jquery
ajax
redirect
Elliot Vargas
sumber
sumber
HttpContext.Response.AddHeader
dan cek pada sukses ajaxsetup adalah cara untuk pergiJawaban:
Saya membaca pertanyaan ini dan menerapkan pendekatan yang telah dinyatakan mengenai pengaturan respons kode status HTTP ke 278 untuk menghindari browser menangani pengalihan secara transparan. Meskipun ini berhasil, saya sedikit tidak puas karena ini sedikit hack.
Setelah menggali lebih dalam, saya membuang pendekatan ini dan menggunakan JSON . Dalam hal ini, semua respons terhadap permintaan AJAX memiliki kode status 200 dan badan respons berisi objek JSON yang dibangun di server. JavaScript pada klien kemudian dapat menggunakan objek JSON untuk memutuskan apa yang perlu dilakukan.
Saya punya masalah serupa dengan Anda. Saya melakukan permintaan AJAX yang memiliki 2 kemungkinan tanggapan: satu yang mengarahkan browser ke halaman baru dan yang menggantikan formulir HTML yang ada di halaman saat ini dengan yang baru. Kode jQuery untuk melakukan ini terlihat seperti:
"Data" objek JSON dibangun di server untuk memiliki 2 anggota:
data.redirect
dandata.form
. Saya menemukan pendekatan ini jauh lebih baik.sumber
Saya memecahkan masalah ini dengan:
Menambahkan tajuk khusus ke respons:
Mengikat fungsi JavaScript ke
ajaxSuccess
acara dan memeriksa untuk melihat apakah header ada:sumber
Tidak ada browser yang menangani respons 301 dan 302 dengan benar. Dan sebenarnya standar bahkan mengatakan mereka harus menanganinya "secara transparan" yang merupakan sakit kepala BESAR untuk vendor Perpustakaan Ajax. Di Ra-Ajax kami terpaksa menggunakan kode status respons HTTP 278 (hanya beberapa kode sukses "tidak terpakai") untuk menangani pengalihan secara transparan dari server ...
Ini benar-benar mengganggu saya, dan jika seseorang di sini memiliki "tarik" di W3C, saya sangat menghargai bahwa Anda dapat memberi tahu W3C bahwa kami benar-benar perlu menangani 301 dan 302 kode sendiri ...! ;)
sumber
Solusi yang akhirnya diterapkan adalah menggunakan pembungkus untuk fungsi panggilan balik panggilan Ajax dan dalam pembungkus ini memeriksa keberadaan elemen tertentu pada potongan HTML yang dikembalikan. Jika elemen ditemukan maka pembungkus melakukan pengalihan. Jika tidak, pembungkus meneruskan panggilan ke fungsi panggilan balik yang sebenarnya.
Misalnya, fungsi pembungkus kami adalah seperti:
Kemudian, ketika melakukan panggilan Ajax kami menggunakan sesuatu seperti:
Ini berhasil bagi kami karena semua panggilan Ajax selalu mengembalikan HTML di dalam elemen DIV yang kami gunakan untuk mengganti bagian halaman. Selain itu, kami hanya perlu mengarahkan ulang ke halaman login.
sumber
Saya suka metode Timmerz dengan sedikit perasan lemon. Jika Anda pernah mendapatkan kembali contentType dari text / html ketika Anda mengharapkan JSON , Anda kemungkinan besar sedang diarahkan. Dalam kasus saya, saya cukup memuat ulang halaman, dan akan diarahkan ke halaman login. Oh, dan periksa bahwa status jqXHR adalah 200, yang tampaknya konyol, karena Anda berada dalam fungsi kesalahan, bukan? Kalau tidak, kasus kesalahan yang sah akan memaksa ulang berulang (oops)
sumber
Gunakan
$.ajax()
panggilan tingkat rendah :Coba ini untuk pengalihan:
sumber
Saya hanya ingin membagikan pendekatan saya karena ini mungkin dapat membantu seseorang:
Saya pada dasarnya termasuk modul JavaScript yang menangani hal-hal otentikasi seperti menampilkan nama pengguna dan juga kasus ini menangani pengalihan ke halaman login .
Skenario saya: Kami pada dasarnya memiliki server ISA di antara yang mendengarkan semua permintaan dan merespons dengan header 302 dan lokasi ke halaman login kami.
Dalam modul JavaScript saya, pendekatan awal saya adalah sesuatu seperti
Masalahnya (seperti banyak di sini sudah disebutkan) adalah bahwa browser menangani pengalihan dengan sendirinya oleh karena itu
ajaxComplete
panggilan balik saya tidak pernah dipanggil, tetapi sebaliknya saya mendapat respon dari halaman Login yang sudah dialihkan yang jelas adalah astatus 200
. Masalahnya: bagaimana Anda mendeteksi apakah respons 200 yang berhasil adalah halaman login Anda yang sebenarnya atau hanya halaman sewenang-wenang lainnya ??Solusinya
Karena saya tidak dapat menangkap 302 redirect response, saya menambahkan
LoginPage
header pada halaman login saya yang berisi url halaman login itu sendiri. Dalam modul saya sekarang mendengarkan header dan melakukan redirect:... dan itu berfungsi seperti pesona :). Anda mungkin bertanya-tanya mengapa saya memasukkan url di
LoginPage
header ... yah pada dasarnya karena saya tidak menemukan cara untuk menentukan url yangGET
dihasilkan dari pengalihan lokasi otomatis darixhr
objek ...sumber
X-
, sehingga header yang lebih baik untuk digunakan akanX-LoginPage: http://example.com/login
.X-
.Saya tahu topik ini sudah lama, tetapi saya akan memberikan pendekatan lain yang saya temukan dan sebelumnya dijelaskan di sini . Pada dasarnya saya menggunakan ASP.MVC dengan WIF (tapi ini tidak terlalu penting untuk konteks topik ini - jawabannya memadai tidak peduli kerangka mana yang digunakan. Petunjuk tetap tidak berubah - berurusan dengan masalah yang berkaitan dengan kegagalan otentikasi saat melakukan permintaan ajax ) .
Pendekatan yang ditunjukkan di bawah ini dapat diterapkan untuk semua permintaan ajax di luar kotak (jika mereka tidak mendefinisikan kembali sebelum acara Kirim jelas).
Sebelum permintaan ajax dijalankan,
CheckPulse
metode dipanggil (metode pengontrol yang bisa menjadi sesuatu yang paling sederhana):Jika pengguna tidak diautentikasi (token telah kedaluwarsa) metode tersebut tidak dapat diakses (dilindungi oleh
Authorize
atribut). Karena kerangka kerja menangani otentikasi, sementara token kedaluwarsa, ia menempatkan http status 302 ke respons. Jika Anda tidak ingin browser Anda menangani 302 respons secara transparan, tangkap di Global.asax dan ubah status respons - misalnya menjadi 200 OK. Selain itu, tambahkan tajuk, yang memerintahkan Anda untuk memproses respons tersebut dengan cara khusus (nanti di sisi klien):Akhirnya di sisi klien periksa tajuk khusus semacam itu. Jika ada - pengalihan penuh ke halaman masuk harus dilakukan (dalam kasus saya
window.location
diganti dengan url dari permintaan yang ditangani secara otomatis oleh kerangka kerja saya).sumber
Saya pikir cara yang lebih baik untuk menangani ini adalah dengan memanfaatkan kode respons protokol HTTP yang ada, khususnya
401 Unauthorized
.Inilah cara saya menyelesaikannya:
Sisi klien: Ikat ke acara ajax
IMO ini lebih umum dan Anda tidak menulis beberapa custom spec / header. Anda juga tidak harus mengubah panggilan ajax yang ada.
Sunting: Komentar Per @ Rob di bawah ini, 401 (kode status HTTP untuk kesalahan otentikasi) harus menjadi indikator. Lihat 403 Forbidden vs 401 Respons HTTP tidak sah untuk detail lebih lanjut. Dengan itu dikatakan beberapa kerangka kerja web menggunakan 403 untuk kedua kesalahan otentikasi DAN otorisasi - jadi beradaptasi sesuai. Rob terima kasih.
sumber
Saya menyelesaikan masalah ini seperti ini:
Tambahkan middleware untuk memproses respons, jika itu merupakan redirect untuk permintaan ajax, ubah respons menjadi respons normal dengan url redirect.
Kemudian di ajaxComplete, jika responsnya berisi redirect, itu harus redirect, jadi ubah lokasi browser.
sumber
Saya punya solusi sederhana yang berfungsi untuk saya, tidak diperlukan perubahan kode server ... cukup tambahkan satu sendok teh pala ...
Saya memeriksa keberadaan tag html, tetapi Anda dapat mengubah indexOf untuk mencari string unik apa pun yang ada di halaman login Anda ...
sumber
Solusi lain yang saya temukan (terutama berguna jika Anda ingin mengatur perilaku global) adalah menggunakan
$.ajaxsetup()
metode ini bersama-sama denganstatusCode
properti . Seperti yang ditunjukkan orang lain, jangan gunakan redirect statuscode (3xx
), alih-alih gunakan4xx
kode status dan tangani redirect sisi klien.Ganti
400
dengan kode status yang ingin Anda tangani. Seperti yang sudah disebutkan401 Unauthorized
bisa menjadi ide bagus. Saya menggunakan400
karena ini sangat tidak spesifik dan saya dapat menggunakan401
untuk kasus yang lebih spesifik (seperti kredensial login yang salah). Jadi, alih-alih mengarahkan ulang secara langsung, backend Anda harus mengembalikan4xx
kode kesalahan ketika sesi habis dan Anda menangani sisi klien redirect. Bekerja sempurna untuk saya bahkan dengan kerangka kerja seperti backbone.jssumber
Sebagian besar solusi yang diberikan menggunakan solusi, menggunakan header tambahan atau kode HTTP yang tidak tepat. Solusi-solusi itu kemungkinan besar akan bekerja tetapi terasa sedikit 'berantakan'. Saya telah menemukan solusi lain.
Kami menggunakan WIF yang dikonfigurasi untuk mengarahkan ulang (passiveRedirectEnabled = "true") pada respons 401. Redirect berguna ketika menangani permintaan normal tetapi tidak akan berfungsi untuk permintaan AJAX (karena browser tidak akan menjalankan 302 / redirect).
Menggunakan kode berikut di global.asax Anda, Anda dapat menonaktifkan redirect untuk permintaan AJAX:
Ini memungkinkan Anda mengembalikan 401 respons untuk permintaan AJAX, yang kemudian dapat ditangani oleh javascript Anda dengan memuat ulang halaman. Reload halaman akan melemparkan 401 yang akan ditangani oleh WIF (dan WIF akan mengarahkan pengguna ke halaman login).
Contoh javascript untuk menangani 401 kesalahan:
sumber
Masalah ini dapat muncul kemudian menggunakan metode ASP.NET MVC RedirectToAction. Untuk mencegah formulir menampilkan respons dalam div, Anda cukup melakukan semacam filter respons ajax untuk respons incomming dengan $ .ajaxSetup . Jika responsnya berisi pengalihan MVC Anda dapat mengevaluasi ekspresi ini di sisi JS. Contoh kode untuk JS di bawah ini:
Jika datanya adalah: "window.location = '/ Acount / Login'" filter di atas akan menangkapnya dan mengevaluasi untuk membuat redirection alih-alih membiarkan data ditampilkan.
sumber
data
ada di badan respons atau tajuk?Menyatukan apa yang dikatakan Vladimir Prudnikov dan Thomas Hansen:
Ini membuat browser memperlakukan respons sebagai sukses, dan menyerahkannya ke Javascript Anda.
sumber
sumber
Mencoba
Letakkan di halaman login. Jika itu dimuat dalam div di halaman utama, itu akan mengarahkan ulang sampai halaman login. "#site" adalah id dari div yang terletak di semua halaman kecuali halaman login.
sumber
Sementara jawaban tampaknya bekerja untuk orang-orang jika Anda menggunakan Spring Security, saya telah menemukan memperluas LoginUrlAuthenticationEntryPoint dan menambahkan kode khusus untuk menangani AJAX lebih kuat. Sebagian besar contoh mencegat semua pengalihan bukan hanya kegagalan otentikasi. Ini tidak diinginkan untuk proyek yang saya kerjakan. Anda mungkin menemukan perlu untuk memperpanjang ExceptionTranslationFilter dan mengganti metode "sendStartAuthentication" untuk menghapus langkah caching jika Anda tidak ingin cache AJAX yang gagal di-cache.
Contoh AjaxAwareAuthenticationEntryPoint:
Sumber: 1 , 2
sumber
Saya memecahkan masalah ini dengan meletakkan yang berikut di halaman login.php saya.
sumber
Biarkan saya kutip lagi masalah seperti yang dijelaskan oleh @Steg
IMHO ini adalah tantangan nyata dan harus secara resmi diperluas ke standar HTTP saat ini.
Saya percaya Standar Http baru akan menggunakan kode status baru. artinya: saat ini
301/302
memberitahu browser untuk pergi dan mengambil konten dari permintaan ini ke yang barulocation
.Dalam standar yang diperluas, itu akan mengatakan bahwa jika respon
status: 308
(hanya sebuah contoh), maka browser harus mengarahkan halaman utama kelocation
disediakan.Yang telah dibilang; Saya cenderung sudah meniru perilaku masa depan ini , dan karena itu ketika document.redirect diperlukan, saya memiliki server merespons sebagai:
Ketika JS mendapat "
status: 204
", ia memeriksa keberadaanx-status: 308
header, dan melakukan document.redirect ke halaman yang disediakan dilocation
header.Apakah ini masuk akal bagi Anda?
sumber
Beberapa mungkin menemukan hal di bawah ini berguna:
Saya ingin klien dialihkan ke halaman login untuk tindakan pemulihan apa pun yang dikirim tanpa token otorisasi. Karena semua tindakan istirahat saya berbasis Ajax, saya membutuhkan cara umum yang baik untuk mengarahkan ulang ke halaman login daripada menangani fungsi sukses Ajax.
Inilah yang telah saya lakukan:
Pada permintaan Ajax apa pun server saya akan mengembalikan respons Json 200 "PERLU OTENTIK" (jika klien perlu mengautentikasi).
Contoh sederhana di Java (sisi server):
Di Javascript saya, saya telah menambahkan kode berikut:
Dan itu saja.
sumber
di servlet Anda harus meletakkan
response.setStatus(response.SC_MOVED_PERMANENTLY);
mengirim status xmlHttp '301' yang Anda perlukan untuk pengalihan ...dan dalam fungsi $ .ajax Anda seharusnya tidak menggunakan
.toString()
fungsi ..., adilif (xmlHttp.status == 301) { top.location.href = 'xxxx.jsp'; }
masalahnya adalah itu tidak terlalu fleksibel, Anda tidak dapat memutuskan di mana Anda ingin mengarahkan ..
mengarahkan melalui servlets harus menjadi cara terbaik. tetapi saya masih belum dapat menemukan cara yang tepat untuk melakukannya.
sumber
Saya hanya ingin mengaitkan permintaan ajax untuk seluruh halaman. @ Super membuat saya mulai. Inilah yang akhirnya saya dapatkan:
Saya ingin secara khusus memeriksa kode status http tertentu untuk mendasarkan keputusan saya. Namun, Anda hanya dapat mengikat ke ajaxError untuk mendapatkan apa pun selain kesuksesan (hanya 200 mungkin?) Saya bisa saja menulis:
sumber
Jika Anda juga ingin meneruskan nilai-nilai maka Anda juga dapat mengatur variabel sesi dan mengakses Mis: Di jsp Anda, Anda dapat menulis
Dan kemudian Anda dapat menyimpan nilai temp ini dalam variabel javascript Anda dan bermain-main
sumber
Saya tidak berhasil dengan solusi header - mereka tidak pernah diambil dalam metode ajaxSuccess / ajaxComplete saya. Saya menggunakan jawaban Steg dengan respons khusus, tetapi saya memodifikasi beberapa sisi JS. Saya mengatur metode yang saya panggil di setiap fungsi sehingga saya dapat menggunakan metode
$.get
dan standar$.post
.Contoh itu digunakan ...
sumber
Akhirnya, saya memecahkan masalah dengan menambahkan kebiasaan
HTTP Header
. Tepat sebelum respons untuk setiap permintaan di sisi server, saya menambahkan url yang diminta saat ini ke header respons.Jenis aplikasi saya di server adalah
Asp.Net MVC
, dan memiliki tempat yang baik untuk melakukannya. diGlobal.asax
i mengimplementasikanApplication_EndRequest
acara jadi:Ini berfungsi sempurna untuk saya! Sekarang di setiap respons dari
JQuery
$.post
saya memilikiurl
header respons yang diminta dan juga lainnya yang datang sebagai hasil dariPOST
metode dengan status302
,303
, ....dan hal penting lainnya adalah tidak perlu memodifikasi kode di sisi server atau sisi klien.
dan selanjutnya adalah kemampuan untuk mendapatkan akses ke informasi lain dari tindakan posting seperti kesalahan, pesan, dan ..., Dengan cara ini.
Saya memposting ini, mungkin membantu seseorang :)
sumber
Saya mengalami masalah ini pada aplikasi Django yang saya mainkan (disclaimer: Saya bermain-main untuk belajar, dan saya sama sekali tidak ahli). Yang ingin saya lakukan adalah menggunakan jQuery ajax untuk mengirim permintaan DELETE ke sumber daya, menghapusnya di sisi server, kemudian mengirim redirect kembali ke (pada dasarnya) beranda. Ketika saya mengirim
HttpResponseRedirect('/the-redirect/')
dari skrip python, metode ajax jQuery menerima 200 bukannya 302. Jadi, yang saya lakukan adalah mengirim respons 300 dengan:Kemudian saya mengirim / menangani permintaan pada klien dengan jQuery.ajax seperti:
Mungkin menggunakan 300 bukan "benar", tetapi setidaknya itu berfungsi seperti yang saya inginkan.
PS: ini sangat menyusahkan untuk diedit pada SO versi mobile. ISP bodoh memasukkan permintaan pembatalan layanan saya tepat ketika saya selesai dengan jawaban saya!
sumber
Anda juga dapat mengaitkan XMLHttpRequest mengirim prototipe. Ini akan bekerja untuk semua pengiriman (jQuery / dojo / etc) dengan satu penangan.
Saya menulis kode ini untuk menangani kesalahan 500 halaman yang kadaluwarsa, tetapi harus berfungsi juga untuk menjebak 200 redirect. Siapkan entri wikipedia di XMLHttpRequest onreadystatechange tentang arti readyState.
sumber
Selain itu Anda mungkin ingin mengarahkan pengguna ke URL header yang diberikan di. Jadi akhirnya akan terlihat seperti ini:
UPD: Opps. Punya tugas yang sama, tetapi tidak berhasil. Melakukan hal ini. Saya akan menunjukkan solusi kepada Anda ketika saya akan menemukannya.
sumber
Saya mendapat solulion yang berfungsi menggunakan jawaban dari tautan @John dan @Arpad dan tautan @RobWinch
Saya menggunakan Spring Security 3.2.9 dan jQuery 1.10.2.
Perpanjang kelas Spring menyebabkan respons 4XX hanya dari permintaan AJAX:
applicationContext-security.xml
Di JSP saya, tambahkan penangan kesalahan global AJAX seperti yang ditunjukkan di sini
Juga, hapus penangan kesalahan yang ada dari panggilan AJAX di halaman JSP:
Saya harap ini membantu orang lain.
Update1 Saya menemukan bahwa saya perlu menambahkan opsi (selalu-gunakan-default-target = "true") ke konfigurasi form-login. Ini diperlukan karena setelah permintaan AJAX dialihkan ke halaman login (karena sesi kedaluwarsa), Spring mengingat permintaan AJAX sebelumnya dan auto redirect ke setelah login. Ini menyebabkan JSON yang dikembalikan ditampilkan pada halaman browser. Tentu saja, bukan yang saya inginkan.
Update2 Alih-alih menggunakan
always-use-default-target="true"
, gunakan contoh @RobWinch untuk memblokir permintaan AJAX dari requstCache. Ini memungkinkan tautan normal untuk diarahkan ke target semula setelah login, tetapi AJAX pergi ke halaman utama setelah login.sumber