"Gemischter Inhalt blockiert", wenn ein HTTP-AJAX-Vorgang auf einer HTTPS-Seite ausgeführt wird

107

Ich habe ein Formular, das ich (über GET, wie es auf diese Weise erforderlich ist) an ein crm (ViciDial) sende. Ich kann das Formular jedoch erfolgreich senden, wenn ich dies tue, gibt die Verarbeitungsdatei bei crm nur einen Erfolgstext wieder und das wars.

Anstelle dieses Textes möchte ich eine Dankesseite auf meiner Website anzeigen. Daher habe ich mich entschieden, AJAX zu verwenden, um das Formular zu senden und es auf die benötigte Seite umzuleiten. In meinem Browser wird jedoch folgende Fehlermeldung angezeigt:

Gemischter Inhalt: Die Seite unter " https://page.com " wurde über HTTPS geladen, forderte jedoch einen unsicheren XMLHttpRequest-Endpunkt " http://XX.XXX.XX.XXX/vicidial/non_agent_api.php?queries=query=data" an '. Diese Anfrage wurde blockiert. Der Inhalt muss über HTTPS bereitgestellt werden.

Dies ist mein AJAX-Skript:

    <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>

Nur das Einstellen von https in der URL funktioniert nicht. Gibt es eine Möglichkeit, die Daten über GET zu übermitteln und den Benutzer auf meine Dankesseite umzuleiten?

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

Problem hier war gemischter Inhalt, dies bedeutet, dass ich eine Seite über HTTPS geladen habe und versucht habe, über AJAX eine API zu treffen, die sich in HTTP befand. Aber der Browser erlaubt uns nicht, das einfach zu tun.

Wenn Sie die API also nicht auf HTTPS einstellen können (dies war mein Fall), können wir dies dennoch auf andere Weise angehen.

Das Hauptproblem war nicht das Problem mit gemischten Inhalten, sondern dass ich Daten an eine API senden und die Benutzer auf eine ausgefallene Dankesseite umleiten wollte. Anstatt AJAX zu verwenden, habe ich eine PHP-Datei erstellt, die die Daten empfängt und sie mit Curl an die API sendet (da dies serverseitig erfolgt, gibt es kein Problem mit gemischten Inhalten) und meinen zufriedenen Benutzer auf eine ausgefallene Dankesseite weiterleitet.

StormRage
quelle
Haben Sie eine sichere Version Ihrer API? Sie müssen über HTTPS anfordern, wenn Sie eine sichere Site als Ursprung verwenden.
Cameron Tinker
1
Nein, weiß ich nicht. Gibt es eine andere Möglichkeit, das zu tun? Ich meine, die Anfrage geht durch, wenn Sie nur das Formular ohne Ajax
StormRage
Sie können in Apache eine HTTPS-URL erstellen, um XX.XXX.XX.XXüber HTTP einen Proxy zu erstellen . Wenn der Zweck von HTTP jedoch darin besteht, Benutzerinformationen zu schützen, müssen Sie darauf achten, dass die Route zwischen Servern nicht über das öffentliche Internet verläuft.
Halfer

Antworten:

89

Wenn Sie eine Seite mit HTTPS in Ihren Browser laden, lehnt der Browser das Laden von Ressourcen über HTTP ab. Wenn Sie die API-URL so geändert haben, dass HTTPS anstelle von HTTP verwendet wird, wird dieses Problem normalerweise behoben . Ihre API darf jedoch keine HTTPS-Verbindungen zulassen. Aus diesem Grund müssen Sie entweder HTTP auf der Hauptseite erzwingen oder anfordern, dass HTTPS-Verbindungen zugelassen werden.

Hinweis dazu: Die Anforderung funktioniert weiterhin, wenn Sie zur API-URL wechseln, anstatt zu versuchen, sie mit AJAX zu laden. Dies liegt daran, dass der Browser keine Ressource aus einer gesicherten Seite lädt, sondern eine unsichere Seite lädt und dies akzeptiert. Damit es jedoch über AJAX verfügbar ist, sollten die Protokolle übereinstimmen.

Mikel Bitson
quelle
1
OK, die API befindet sich auf meinem Server. Gibt es eine Anleitung, die ich befolgen kann, um https zu erstellen?
StormRage
1
@StormRage Auf jeden Fall! Welchen Servertyp betreiben Sie? Apache? Ist es Shared Hosting oder ein privater Server?
Mikel Bitson
@StormRage Bitte lassen Sie mich wissen, wenn Sie weitere Hilfe benötigen. Andernfalls wird durch die Abstimmung ein Anreiz für die öffentliche Unterstützung geschaffen, die Sie hier auf SO erhalten.
Mikel Bitson
1
Es tut mir leid, dass ich zu spät gekommen bin. Ich habe es geschafft, es ohne AJAX zu lösen. Meine Lösungen enthalten einige WordPress-Funktionen / PHP-Curl. Ich werde meine Lösung so schnell wie möglich veröffentlichen, sollte ich nur meine Frage bearbeiten und meine Lösung darin schreiben, oder sollte ich die Schaltfläche "Beantworte deine eigene Frage" verwenden?
StormRage
1
Habe hier den relevanten Teil der Antwort hervorgehoben. Die einzige praktische Lösung hierfür ist die Verwendung von HTTPS
Liam
129

Ich habe dieses Problem behoben, indem ich der HTML-Seite folgenden Code hinzugefügt habe, da wir die Drittanbieter-API verwenden, die nicht von uns gesteuert wird.

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

Hoffe, das würde helfen, und für eine Aufzeichnung auch.

Himmel
quelle
8
Dadurch werden alle httpzu verwendenden Anforderungen aktualisiert https, sodass Sie das Protokoll nicht für jeden Anruf ändern müssen.
Am
3
Das hat bei mir funktioniert, aber leider funktioniert das nicht mit Internet Explorer: developer.mozilla.org/en-US/docs/Web/HTTP/Headers/…
Ciaran Gallagher
2
Ich habe es versucht, aber jetzt erhalte ich einen CORS-Fehler auf Firefox und net :: ERR_SSL_PROTOCOL_ERROR auf Chrome. Ich weiß, dass alle Anrufe funktionieren, weil meine Webseite vorher http war, aber jetzt, wo ich zu https gewechselt habe, funktionieren diese Anrufe nicht. Gibt es noch etwas, das ich meiner Haupt-HTML-Datei hinzufügen kann? Denn wenn ich den Schritten von @Juanma Menendez folge, funktionieren alle Anrufe, aber ich kann nicht erwarten, dass jeder Benutzer dies tut.
Otorrinolaringologista -man
Ich habe stundenlang mit diesem Problem zu kämpfen, bis ich Ihre Antwort gefunden habe, vielen Dank!
Muhab
Wir bestätigen, dass diese Lösung in unserem Fall funktioniert, vielleicht helfen sie Ihnen auch in Zukunft: Wir haben versucht, eine segmentierte HTTP-Live-Streaming- / Video-on-Demand-Funktion einzurichten, etwa www.example.com/blabla/master.m3u8. Auf http hat alles gut funktioniert. Aber wenn wir es auf https migrieren, funktioniert es einfach nicht. Wir haben herausgefunden, dass die Initiale master.m3u8eine httpsAnforderung ausführen konnte , aber der folgende segmentierte Videoblock wurde immer verwendet http(da wir ein Modul eines Drittanbieters verwenden). Egal was wir optimieren, es wird einfach nicht verwendet https. Verwendete diese Richtlinie und arbeitete sofort wie ein Zauber!
Rahmatns
34

Wenn Sie nur eine Webseite besuchen, der Sie vertrauen, und schnell vorankommen möchten, gehen Sie einfach wie folgt vor:

1- Klicken Sie auf das Schildsymbol ganz rechts in der Adressleiste.

Zulassen gemischter Inhalte in Google Chrome

2- Klicken Sie im Popup-Fenster auf "Trotzdem laden" oder "Unsicheres Skript laden" (abhängig von Ihrer Chrome-Version).


Wenn Sie Ihren Chrome-Browser IMMER (auf allen Webseiten) einstellen möchten, lassen Sie gemischte Inhalte zu:

1- Drücken Sie in einem geöffneten Chrome-Browser Strg + Umschalt + Q auf Ihrer Tastatur, um das Schließen von Chrome zu erzwingen. Chrome muss vor den nächsten Schritten vollständig geschlossen sein.

2- Klicken Sie mit der rechten Maustaste auf das Google Chrome-Desktopsymbol (oder den Link zum Startmenü). Wählen Sie Eigenschaften.

3- Fügen Sie am Ende der vorhandenen Informationen im Feld Ziel Folgendes hinzu: "--allow-running-unsicherer Inhalt" (Vor dem ersten Bindestrich steht ein Leerzeichen.)

4- Klicken Sie auf OK.

5- Öffnen Sie Chrome und versuchen Sie, den zuvor blockierten Inhalt zu starten. Es sollte jetzt funktionieren.

Juanma Menendez
quelle
4
Dies bedeutet nichts für Benutzer, die Websites für Benutzer entwerfen, die ihre Einstellungen nicht ändern möchten, damit die Website in ihrem Browser funktioniert, z. B. im OP.
Smallpants
12

Der Grund für diesen Fehler ist sehr einfach. Ihr AJAX versucht, über HTTP anzurufen, während Ihr Server über HTTPS ausgeführt wird. Daher verweigert Ihr Server den Anruf Ihres AJAX. Dies kann behoben werden, indem die folgende Zeile in das Head-Tag Ihrer Haupt-HTML-Datei eingefügt wird:

<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests"> 
Sobhan Niroula
quelle
es erlaubt es, aber die Anfrage ist https
BG BRUNO
In meinem Fall. die Server nur HTTP-Anfrage. Ich versuche das <meta> kann nicht funktionieren. Der Browser sagt Anforderungsfehler bei URL.
iHad 169
1

Wenn Ihr API-Code auf einem node.js- Server ausgeführt wird, müssen Sie Ihre Aufmerksamkeit dort konzentrieren, nicht in Apache oder NGINX. Mikel hat recht, das Ändern der API-URL in HTTPS ist die Antwort, aber wenn Ihre API einen node.js-Server aufruft, sollte sie besser für HTTPS eingerichtet werden! Und natürlich kann sich der node.js-Server an jedem nicht verwendeten Port befinden, es muss nicht Port 443 sein.

mcmacerson
quelle
Die API war von Drittanbietern, daher konnte ich sie auf keinen Fall auf https setzen. Wie Sie in der URL sehen können, die ich zu treffen versuchte, wurde die API in PHP
StormRage am
@StormRage Ihre Frage und Mikels Antwort führten zu einer Lösung für mein Problem, daher dachte ich, ich würde es hier notieren, obwohl meine Antwort nicht wirklich auf Ihre Situation zutrifft.
mcmacerson
Nun, Sie und Mikel haben Recht, die vernünftigste Lösung wäre, ssl in der API zu verwenden, aber in diesem Zusammenhang war ich nicht in der Lage, dies zu tun, da es sich um eine API eines Drittanbieters handelte, sondern um eine Lösung für ppl mit WordPress oder Jede ältere Site kann die Daten an ihr Backend senden und die Anforderung an die API innerhalb des Servers senden.
StormRage
Ich implementierte API von Laravel als Server-Seite und ionische Anwendung als PWA auf demselben Host, so dass ich den gleichen Fehler habe, der in diesem Artikel erwähnt wird. stackoverflow.com/q/56157129/308578
saber tabatabaee yazdi
1

Anstatt die Ajax Post-Methode zu verwenden, können Sie zusammen mit dem Element ein dynamisches Formular verwenden. Es funktioniert auch dann, wenn die Seite in SSL geladen ist und die übermittelte Quelle kein SSL ist.

Sie müssen den Wert des Formularelements festlegen.

Tatsächlich wird ein neues dynamisches Formular als Nicht-SSL-Modus in einer separaten Registerkarte des Browsers geöffnet, wenn das Zielattribut '_blank' gesetzt hat.

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
quelle
Eigentlich möchte ich eine API treffen, aber wenn ich es mit Ihrer Methode mache, indem ich eine Get-Anfrage mache, würde ich tatsächlich ein Formular senden, aber jetzt kann ich die Antwort von der API nicht mehr zurücklesen. Weil ich denke, dass AJAX oder xmlhttprequest die einzige Option ist
Siddharth Choudhary
interessante Lösung :-)
BG BRUNO
einfach und brillant
Harkal
0

Ich war das gleiche Problem, aber für mich war das Problem ng build command. Ich habe "ng build --prod" gemacht. Ich habe es auf "ng build --prod --base-href / applicationname /" korrigiert. und das löste mein Problem.

Narender Gandi
quelle
0

In meinem Fall war mein localhost httpund meine bereitgestellte Version https, daher habe ich dieses Skript verwendet, um ein http-equiv-Meta-Tag nur für https hinzuzufügen:

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
quelle