Saya telah melakukan banyak penelitian dan tidak dapat menemukan cara untuk mengatasinya. Saya mencoba melakukan panggilan jQuery ajax dari server https ke server https locahost yang menjalankan jetty dengan sertifikat yang ditandatangani sendiri. Masalah saya adalah saya tidak dapat menentukan apakah responsnya adalah koneksi yang ditolak atau respons yang tidak aman (karena kurangnya penerimaan sertifikat). Adakah cara untuk menentukan perbedaan antara kedua skenario? Itu responseText
, dan statusCode
selalu sama di kedua kasus, meskipun di konsol chrome saya dapat melihat perbedaannya:
net::ERR_INSECURE_RESPONSE
net::ERR_CONNECTION_REFUSED
responseText
selalu "" dan statusCode
selalu "0" untuk kedua kasus.
Pertanyaan saya adalah, bagaimana saya bisa menentukan apakah panggilan ajax jQuery gagal karena ERR_INSECURE_RESPONSE
atau karena ERR_CONNECTION_REFUSED
?
Setelah sertifikat diterima semuanya berfungsi dengan baik, tetapi saya ingin tahu apakah server localhost dimatikan, atau aktif dan berjalan tetapi sertifikat belum diterima.
$.ajax({
type: 'GET',
url: "https://localhost/custom/server/",
dataType: "json",
async: true,
success: function (response) {
//do something
},
error: function (xhr, textStatus, errorThrown) {
console.log(xhr, textStatus, errorThrown); //always the same for refused and insecure responses.
}
});
Bahkan melakukan permintaan secara manual saya mendapatkan hasil yang sama:
var request = new XMLHttpRequest();
request.open('GET', "https://localhost/custom/server/", true);
request.onload = function () {
console.log(request.responseText);
};
request.onerror = function () {
console.log(request.responseText);
};
request.send();
sumber
function (xhr, status, msg) {...
Saya ragu mereka akan melakukannya, tetapi patut dicoba.Jawaban:
Tidak ada cara untuk membedakannya dari Browser Web terbaru.
Spesifikasi W3C:
Seperti yang bisa Anda baca, kesalahan jaringan tidak menyertakan respons HTTP yang menyertakan kesalahan, itulah sebabnya Anda akan selalu mendapatkan 0 sebagai kode status, dan "" sebagai kesalahan.
Sumber
Catatan : Contoh berikut dibuat menggunakan Google Chrome Versi 43.0.2357.130 dan terhadap lingkungan yang saya buat untuk meniru OP satu. Kode untuk mengaturnya ada di bagian bawah jawaban.
Saya berpikir bahwa pendekatan Untuk mengatasi ini akan membuat permintaan sekunder melalui HTTP daripada HTTPS sebagai jawaban ini tetapi saya ingat itu tidak mungkin karena versi browser yang lebih baru memblokir konten campuran.
Artinya, Browser Web tidak akan mengizinkan permintaan melalui HTTP jika Anda menggunakan HTTPS dan sebaliknya.
Ini sudah seperti ini sejak beberapa tahun yang lalu tetapi versi Browser Web yang lebih lama seperti Mozilla Firefox di bawahnya versi 23 memungkinkannya.
Bukti tentang itu:
Membuat permintaan HTTP dari HTTPS menggunakan konsol Web Broser
akan menghasilkan kesalahan berikut:
Kesalahan yang sama akan muncul di konsol browser jika Anda mencoba melakukan ini dengan cara lain seperti menambahkan Iframe.
Menggunakan koneksi Socket juga diposting sebagai jawaban , saya cukup yakin bahwa hasilnya akan sama / mirip tetapi saya sudah mencobanya.
Mencoba membuka koneksi soket dari Web Broswer menggunakan HTTPS ke titik akhir soket non Secure akan berakhir dengan kesalahan konten campuran.
Kemudian saya mencoba menyambung ke titik akhir wss juga, lihat Jika saya dapat membaca beberapa informasi tentang kesalahan koneksi jaringan:
Pelaksana cuplikan di atas dengan Server dimatikan menghasilkan:
Menjalankan cuplikan di atas dengan Server Diaktifkan
Tetapi sekali lagi, kesalahan bahwa "fungsi onerror" yang dihasilkan ke konsol tidak memiliki tip untuk membedakan satu kesalahan dari yang lain.
Menggunakan proxy sebagai saran jawaban ini dapat bekerja tetapi hanya jika server "target" memiliki akses publik.
Ini tidak terjadi di sini, jadi mencoba menerapkan proxy dalam skenario ini akan membawa Kami ke masalah yang sama.
Kode untuk membuat server HTTPS Node.js :
Saya telah membuat dua server HTTPS Nodejs, yang menggunakan sertifikat yang ditandatangani sendiri:
targetServer.js:
applicationServer.js:
Untuk membuatnya bekerja, Anda harus memiliki Nodejs Terinstal, Perlu membuat sertifikat terpisah untuk setiap server dan menyimpannya di folder certs dan certs2 yang sesuai.
Untuk menjalankannya cukup jalankan
node applicationServer.js
dannode targetServer.js
di terminal (contoh ubuntu).sumber
Sampai sekarang: Tidak ada cara untuk membedakan acara ini di antara pengguna browser. Karena browser tidak menyediakan acara untuk diakses oleh pengembang. (Juli 2015)
Jawaban ini hanya berusaha memberikan ide-ide untuk solusi yang potensial, meskipun hacky dan tidak lengkap.
Penafian: jawaban ini tidak lengkap karena tidak sepenuhnya menyelesaikan masalah OP (karena kebijakan lintas sumber). Namun gagasan itu sendiri memiliki beberapa manfaat yang dikembangkan lebih lanjut oleh: @artur grzesiak di sini , menggunakan proxy dan ajax.
Setelah melakukan sedikit penelitian sendiri, tampaknya tidak ada bentuk pengecekan kesalahan apa pun untuk perbedaan antara koneksi ditolak dan respons tidak aman, setidaknya sejauh javascript memberikan respons untuk perbedaan antara keduanya.
Konsensus umum penelitian saya adalah bahwa sertifikat SSL ditangani oleh browser, jadi sampai sertifikat yang ditandatangani sendiri diterima oleh pengguna, browser mengunci semua permintaan, termasuk yang untuk kode status. Browser dapat (jika dikodekan) mengirim kembali kode statusnya sendiri untuk respons yang tidak aman, tetapi itu tidak benar-benar membantu apa pun, dan bahkan kemudian, Anda akan memiliki masalah dengan kompatibilitas browser (chrome / firefox / IE memiliki standar yang berbeda. .. sekali lagi)
Karena pertanyaan awal Anda adalah untuk memeriksa status server Anda antara aktif versus memiliki sertifikat yang tidak diterima, tidak bisakah Anda membuat permintaan HTTP standar seperti itu?
Memang ini membutuhkan permintaan tambahan untuk memverifikasi konektivitas server, tetapi itu harus menyelesaikan pekerjaan dengan proses eliminasi. Masih terasa hacky, dan saya bukan penggemar permintaan berlipat ganda.
sumber
@ Jawaban Schultzie cukup dekat, tetapi jelas
http
- secara umum - tidak akan berfungsi darihttps
dalam lingkungan browser.Apa yang dapat Anda lakukan adalah menggunakan server perantara (proxy) untuk membuat permintaan atas nama Anda. Proksi harus memungkinkan untuk meneruskan
http
permintaan darihttps
asal atau untuk memuat konten dari sumber yang ditandatangani sendiri .Memiliki server Anda sendiri dengan sertifikat yang tepat mungkin berlebihan dalam kasus Anda - karena Anda dapat menggunakan setelan ini alih-alih mesin dengan sertifikat yang ditandatangani sendiri - tetapi ada banyak layanan proxy terbuka anonim di luar sana.
Jadi dua pendekatan yang muncul di benak saya adalah:
.parentWindow
. Jika jendela Anda menerima pesan, Anda dapat yakin bahwa server sedang berjalan (atau lebih tepatnya berjalan sepersekian detik sebelumnya).Jika Anda hanya tertarik dengan lingkungan lokal Anda, Anda dapat mencoba menjalankan chrome dengan
--disable-web-security
bendera.Saran lain: apakah Anda mencoba memuat gambar secara terprogram untuk mengetahui apakah ada lebih banyak info di sana?
sumber
Lihat jQuery.ajaxError () Diambil referensi dari: Penanganan Kesalahan AJAX jQuery (Kode Status HTTP) Ini menangkap kesalahan Ajax global yang dapat Anda tangani dengan berbagai cara melalui HTTP atau HTTPS:
sumber
Sayangnya, API XHR browser saat ini tidak memberikan indikasi eksplisit kapan browser menolak untuk terhubung karena "respons tidak aman", dan juga saat browser tidak mempercayai sertifikat HTTP / SSL situs web.
Tetapi ada cara untuk mengatasi masalah ini.
Salah satu solusi yang saya buat untuk menentukan kapan browser tidak mempercayai sertifikat HTTP / SSL, adalah pertama-tama mendeteksi jika kesalahan XHR telah terjadi (misalnya menggunakan
error()
panggilan balik jQuery ), kemudian periksa apakah panggilan XHR ke 'https : // 'URL, lalu periksa apakah XHRreadyState
nya 0, yang berarti koneksi XHR belum dibuka (yang terjadi jika browser tidak menyukai sertifikat).Inilah kode tempat saya melakukan ini: https://github.com/maratbn/RainbowPayPress/blob/e9e9472a36ced747a0f9e5ca9fa7d96959aeaf8a/rainbowpaypress/js/le_requirejs/public/model_info__transaction_details.js#L88
sumber
Saya rasa saat ini tidak ada cara untuk mendeteksi pesan kesalahan ini, tetapi peretasan yang dapat Anda lakukan adalah menggunakan server seperti nginx di depan server aplikasi Anda, sehingga jika server aplikasi mati Anda akan mendapatkan yang buruk. kesalahan gateway dari nginx dengan
502
kode status yang dapat Anda deteksi di JS. Jika tidak, jika sertifikat tidak valid, Anda masih akan mendapatkan kesalahan umum yang sama denganstatusCode = 0
.sumber