"Konten campuran diblokir" saat menjalankan operasi HTTP AJAX di halaman HTTPS

110

Saya memiliki formulir yang saya kirimkan (melalui GET seperti yang diperlukan dengan cara ini) ke crm (ViciDial). Saya berhasil mengirimkan formulir namun jika saya melakukannya, file pemrosesan di crm hanya akan menggemakan teks yang berhasil dan hanya itu.

Alih-alih teks itu, saya ingin menampilkan halaman terima kasih di situs web saya, jadi saya memutuskan untuk menggunakan AJAX untuk mengirimkan formulir dan mengarahkannya ke halaman yang saya butuhkan, namun saya mendapatkan kesalahan ini di browser saya:

Konten Campuran: Halaman di ' https://page.com ' dimuat melalui HTTPS, tetapi meminta titik akhir XMLHttpRequest yang tidak aman ' http://XX.XXX.XX.XXX/vicidial/non_agent_api.php?queries=query=data '. Permintaan ini telah diblokir; konten harus disajikan melalui HTTPS.

Ini adalah skrip AJAX saya:

    <script>
    SubmitFormClickToCall = function(){

        jQuery.ajax({
            url: "http://XX.XXX.XX.XX/vicidial/non_agent_api.php",
            data : jQuery("#form-click-to-call").serialize(),
            type : "GET",
            processData: false,
            contentType: false,
            success: function(data){
                window.location.href = "https://www.example.com/thank-you";
            }
        });
    }
    </script>

Hanya mengatur https di URL tidak akan berfungsi, adakah cara untuk mengirimkan data melalui GET dan mengarahkan pengguna ke halaman terima kasih saya?

============================

Masalah di sini adalah konten campuran, ini berarti saya memuat halaman melalui HTTPS dan mencoba menekan melalui AJAX API yang ada di HTTP. Tapi browser tidak mengizinkan kita melakukan itu.

Jadi, jika Anda tidak dapat menyetel API menjadi HTTPS (ini kasus saya), kami masih dapat melakukan pendekatan ini dengan cara yang berbeda.

Masalah Utama bukanlah masalah konten campuran, tetapi saya ingin mengirimkan data ke API dan mengarahkan pengguna ke halaman terima kasih yang mewah. Alih-alih menggunakan AJAX, saya membuat file php yang menerima data mengirimkannya menggunakan curl ke API (karena ini dilakukan di sisi server tidak ada masalah konten campuran) dan mengarahkan pengguna saya yang bahagia ke halaman terima kasih yang mewah.

StormRage
sumber
Apakah Anda memiliki versi aman dari API Anda? Anda harus meminta melalui HTTPS jika Anda menggunakan situs aman sebagai asalnya.
Cameron Tinker
1
Tidak, saya tidak tahu, apakah ada cara lain untuk melakukan itu? Maksud saya, permintaan tersebut akan
diproses
Anda dapat membuat URL HTTPS di Apache ke proxy ke XX.XXX.XX.XXmelalui HTTP. Namun, jika tujuan HTTP adalah untuk melindungi informasi pengguna, Anda harus berhati-hati agar rute antar server tidak melalui internet publik.
halfer

Jawaban:

92

Jika Anda memuat halaman di browser Anda menggunakan HTTPS, browser akan menolak untuk memuat sumber daya apa pun melalui HTTP. Seperti yang Anda coba, mengubah URL API menjadi HTTPS dan bukan HTTP biasanya menyelesaikan masalah ini . Namun, API Anda tidak boleh mengizinkan koneksi HTTPS. Karena itu, Anda harus memaksa HTTP di halaman utama atau meminta mereka mengizinkan koneksi HTTPS.

Catatan tentang ini: Permintaan akan tetap berfungsi jika Anda membuka URL API alih-alih mencoba memuatnya dengan AJAX. Ini karena browser tidak memuat sumber daya dari dalam halaman aman, melainkan memuat halaman yang tidak aman dan menerimanya. Namun, agar tersedia melalui AJAX, protokolnya harus cocok.

Mikel Bitson
sumber
1
Oke, api ada di server saya, apakah ada panduan yang bisa saya ikuti untuk membuatnya https?
StormRage
1
@StormRage Tentu! Jenis server apa yang Anda jalankan? Apache? Apakah itu shared hosting atau private server?
Mikel Bitson
@StormRage Beri tahu saya jika Anda membutuhkan bantuan lebih lanjut. Jika tidak, pemungutan suara akan memberi insentif pada bantuan publik yang Anda dapatkan di SO.
Mikel Bitson
1
Maaf karena terlambat dalam hal ini, saya berhasil menyelesaikannya tanpa menggunakan AJAX, solusi saya menyertakan beberapa fungsi wordpress / php curl, posting solusi saya secepat mungkin, haruskah saya mengedit pertanyaan saya dan menulis solusi saya di dalamnya, atau haruskah saya menggunakan tombol yang bertuliskan "jawab pertanyaan Anda sendiri"?
StormRage
1
Soroti bagian yang relevan dari jawaban di sini. Satu-satunya solusi praktis untuk ini adalah dengan menggunakan HTTPS
Liam
131

Saya menyelesaikan ini dengan menambahkan kode berikut ke halaman HTML, karena kami menggunakan API pihak ketiga yang tidak dikontrol oleh kami.

<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests"> 

Semoga ini bisa membantu, dan sebagai catatan juga.

Langit
sumber
8
Ini meningkatkan semua httppermintaan untuk digunakan https, jadi Anda tidak perlu mengubah protokol untuk setiap panggilan.
eithed
3
Ini berhasil untuk saya, tetapi sayangnya ini tidak berfungsi dengan Internet Explorer: developer.mozilla.org/en-US/docs/Web/HTTP/Headers/…
Ciaran Gallagher
2
Saya sudah mencoba ini tetapi sekarang saya mendapatkan kesalahan CORS pada firefox dan net :: ERR_SSL_PROTOCOL_ERROR di chrome. Saya tahu semua panggilan berfungsi karena halaman web saya sebelumnya http tetapi sekarang saya berubah menjadi https panggilan ini tidak berfungsi. apakah ada hal lain yang bisa saya tambahkan ke file html utama saya? Karena jika saya mengikuti langkah @Juanma Menendez, semua panggilan berfungsi tetapi saya tidak dapat mengharapkan setiap pengguna melakukan ini.
Otorrinolaringologista -man
Saya telah berjuang dengan masalah ini selama berjam-jam sampai saya menemukan jawaban Anda, terima kasih banyak!
Muhab
Kami mengonfirmasi bahwa solusi ini berfungsi pada kasus kami, mungkin akan membantu Anda juga di masa mendatang: Kami mencoba membuat fitur HTTP live streaming / video on demand tersegmentasi, seperti www.example.com/blabla/master.m3u8. Semuanya bekerja dengan baik di http. Tetapi ketika kita memigrasikannya ke https itu tidak akan berhasil. Kami menemukan bahwa yang awal master.m3u8dapat melakukan httpspermintaan, tetapi potongan video berikut selalu menggunakan http(karena kami menggunakan modul pihak ketiga). Tidak peduli apa yang kita atur, itu tidak akan digunakan https. Menggunakan kebijakan ini dan bekerja seketika seperti jimat!
rahmatns
34

Jika Anda baru saja mengunjungi laman web yang Anda percaya dan ingin maju cepat, cukup:

1- Klik ikon perisai di ujung kanan bilah alamat.

Izinkan konten campuran di Google Chrome

2- Di jendela pop-up, klik "Tetap muat" atau "Muat skrip yang tidak aman" (bergantung pada versi Chrome Anda).


Jika Anda ingin menyetel browser Chrome Anda ke SELALU (di semua halaman web) izinkan konten campuran:

1- Di browser Chrome yang terbuka, tekan Ctrl + Shift + Q pada keyboard Anda untuk menutup paksa Chrome. Chrome harus ditutup sepenuhnya sebelum langkah selanjutnya.

2- Klik kanan ikon desktop Google Chrome (atau tautan Start Menu). Pilih Properties.

3- Di akhir informasi yang ada di bidang Target, tambahkan: "--allow-running-insecure-content" (Ada spasi sebelum tanda hubung pertama.)

4- Klik OK.

5- Buka Chrome dan coba luncurkan konten yang diblokir sebelumnya. Ini harus bekerja sekarang.

Juanma Menendez
sumber
4
Ini tidak berguna bagi orang yang mendesain situs web untuk pengguna yang tidak ingin mengubah pengaturan mereka untuk membuat situs berfungsi di browser mereka, misalnya, OP.
smallpants
12

Alasan kesalahan ini sangat sederhana. AJAX Anda mencoba memanggil melalui HTTP sedangkan server Anda berjalan melalui HTTPS, sehingga server Anda menolak memanggil AJAX Anda. Ini dapat diperbaiki dengan menambahkan baris berikut di dalam tag head file HTML utama Anda:

<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests"> 
Sobhan Niroula
sumber
itu mengizinkannya tetapi permintaannya adalah https
BG BRUNO
Dalam kasus saya. permintaan HTTP hanya server. Saya coba ini <meta> tidak bisa bekerja. Browser mengatakan kesalahan permintaan di URL.
iHad 169
1

Jika kode API Anda berjalan di server node.js maka Anda perlu memfokuskan perhatian Anda di sana, bukan di Apache atau NGINX. Mikel benar, mengubah URL API menjadi HTTPS adalah jawabannya, tetapi jika API Anda memanggil server node.js, sebaiknya disiapkan untuk HTTPS! Dan tentu saja, server node.js dapat berada di port mana pun yang tidak digunakan, tidak harus port 443.

mcmacerson.dll
sumber
API adalah pihak ketiga, jadi tidak mungkin saya dapat menyetelnya ke https, dan seperti yang Anda lihat di url yang saya coba tekan, API tersebut diberi kode dalam PHP
StormRage
@StormRage Pertanyaan Anda dan jawaban Mikel mengarah pada solusi untuk masalah saya, jadi saya pikir saya akan mencatatnya di sini meskipun jawaban saya tidak benar-benar sesuai dengan situasi Anda.
mcmacerson
Nah, Anda dan Mikel benar, solusi yang paling masuk akal adalah menggunakan ssl di API, tetapi dalam konteks ini saya tidak dapat melakukannya karena itu adalah API pihak ke-3, tetapi solusi untuk ppl menggunakan wordpress atau situs lama apa pun dapat mengirim data ke backend mereka dan mengirim permintaan ke API di dalam server.
StormRage
saya mengimplementasikan api oleh laravel sebagai sisi server dan aplikasi ionik sebagai PWA pada host yang sama jadi saya memiliki kesalahan yang sama disebutkan dalam artikel ini stackoverflow.com/q/56157129/308578
saber tabatabaee yazdi
1

Daripada menggunakan metode Ajax Post, Anda dapat menggunakan bentuk dinamis bersama dengan elemen. Ini akan bekerja bahkan halaman dimuat dalam SSL dan sumber yang dikirimkan adalah non SSL.

Anda perlu mengatur nilai nilai elemen formulir.

Sebenarnya bentuk dinamis baru akan terbuka sebagai mode non SSL di tab terpisah di Browser ketika atribut target telah disetel '_blank'

var f = document.createElement('form');
f.action='http://XX.XXX.XX.XX/vicidial/non_agent_api.php';
f.method='POST';
//f.target='_blank';
//f.enctype="multipart/form-data"

var k=document.createElement('input');
k.type='hidden';k.name='CustomerID';
k.value='7299';
f.appendChild(k);



//var z=document.getElementById("FileNameId")
//z.setAttribute("name", "IDProof");
//z.setAttribute("id", "IDProof");
//f.appendChild(z);

document.body.appendChild(f);
f.submit()
Proneet Ray
sumber
Saya sebenarnya ingin masuk ke API, tetapi ketika saya melakukannya dengan metode Anda dengan membuat permintaan get, saya sebenarnya akan mengirimkan formulir tetapi sekarang saya terjebak dengan membaca tanggapan kembali dari API. Karena saya kira untuk permintaan AJAX atau xmlhttprequest itu adalah satu-satunya pilihan
Siddharth Choudhary
solusi intereting :-)
BG BRUNO
sederhana dan cemerlang
Harkal
0

Saya masalah yang sama, tapi bagi saya masalahnya ng build command. Saya melakukan "ng build --prod" saya telah mengoreksinya menjadi "ng build --prod --base-href / applicationname /". dan ini memecahkan masalah saya.

Narender Gandi
sumber
0

dalam kasus saya, localhost saya adalah httpdan versi yang saya terapkan adalah https, jadi saya menggunakan skrip ini untuk menambahkan tag meta http-equiv hanya untuk https:

if (window.location.protocol.indexOf('https') == 0){
  var el = document.createElement('meta')
  el.setAttribute('http-equiv', 'Content-Security-Policy')
  el.setAttribute('content', 'upgrade-insecure-requests')
  document.head.append(el)
}
yaya
sumber