Laden eines domänenübergreifenden Endpunkts mit AJAX

131

Ich versuche, eine domänenübergreifende HTML-Seite mit AJAX zu laden, aber wenn der Datentyp nicht "jsonp" ist, kann ich keine Antwort erhalten. Bei Verwendung von jsonp erwartet der Browser jedoch einen Skript-MIME-Typ, empfängt jedoch "text / html".

Mein Code für die Anfrage lautet:

$.ajax({
    type: "GET",
    url: "http://saskatchewan.univ-ubs.fr:8080/SASStoredProcess/do?_username=DARTIES3-2012&_password=P@ssw0rd&_program=%2FUtilisateurs%2FDARTIES3-2012%2FMon+dossier%2Fanalyse_dc&annee=2012&ind=V&_action=execute",
    dataType: "jsonp",
}).success( function( data ) {
    $( 'div.ajax-field' ).html( data );
});

Gibt es eine Möglichkeit, die Verwendung von jsonp für die Anfrage zu vermeiden? Ich habe bereits versucht, den Parameter crossDomain zu verwenden, aber es hat nicht funktioniert.

Wenn nicht, gibt es eine Möglichkeit, den HTML-Inhalt in jsonp zu empfangen? Derzeit sagt die Konsole in der jsonp-Antwort "unerwartet <".

xonorageous
quelle
Ich habe das Problem gelöst, indem ich eine proxy.php erstellt habe, wie hier erläutert. Scode7.blogspot.com/2019/11/…
CodeDezk

Antworten:

235

jQuery Ajax Notes

  • Aufgrund von Sicherheitsbeschränkungen des Browsers unterliegen die meisten Ajax- Anforderungen derselben Ursprungsrichtlinie . Die Anforderung kann Daten aus einer anderen Domäne, Subdomäne, einem anderen Port oder einem anderen Protokoll nicht erfolgreich abrufen.
  • Skript- und JSONP-Anforderungen unterliegen nicht denselben Einschränkungen für Ursprungsrichtlinien.

Es gibt einige Möglichkeiten, die domänenübergreifende Barriere zu überwinden :

Es gibt einige Plugins, die bei domänenübergreifenden Anfragen helfen :

Kopf hoch!

Der beste Weg, um dieses Problem zu lösen, besteht darin, einen eigenen Proxy im Back-End zu erstellen, sodass Ihr Proxy auf die Dienste in anderen Domänen verweist, da im Back-End nicht dieselbe Einschränkung für Ursprungsrichtlinien vorhanden ist . Wenn Sie dies im Back-End nicht tun können, beachten Sie die folgenden Tipps.


Warnung!

Die Verwendung von Proxys von Drittanbietern ist keine sichere Vorgehensweise, da sie Ihre Daten verfolgen können, sodass sie mit öffentlichen Informationen verwendet werden können, jedoch niemals mit privaten Daten.


Die unten gezeigten Codebeispiele verwenden jQuery.get () und jQuery.getJSON () . Beide sind Kurzmethoden von jQuery.ajax ()


CORS überall

CORS Anywhere ist ein node.js-Proxy, der der Proxy-Anforderung CORS-Header hinzufügt.
Um die API zu verwenden, stellen Sie der URL einfach die API-URL voran. (Unterstützt https : siehe Github-Repository )

Wenn Sie domänenübergreifende Anforderungen bei Bedarf automatisch aktivieren möchten, verwenden Sie das folgende Snippet:

$.ajaxPrefilter( function (options) {
  if (options.crossDomain && jQuery.support.cors) {
    var http = (window.location.protocol === 'http:' ? 'http:' : 'https:');
    options.url = http + '//cors-anywhere.herokuapp.com/' + options.url;
    //options.url = "http://cors.corsproxy.io/url=" + options.url;
  }
});

$.get(
    'http://en.wikipedia.org/wiki/Cross-origin_resource_sharing',
    function (response) {
        console.log("> ", response);
        $("#viewer").html(response);
});


Welchen Ursprung auch immer

Was auch immer Origin ist ein domänenübergreifender Jsonp- Zugriff. Dies ist eine Open Source-Alternative zu anyorigin.com .

Um die Daten von google.com abzurufen , können Sie dieses Snippet verwenden:

// It is good specify the charset you expect.
// You can use the charset you want instead of utf-8.
// See details for scriptCharset and contentType options: 
// http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings
$.ajaxSetup({
    scriptCharset: "utf-8", //or "ISO-8859-1"
    contentType: "application/json; charset=utf-8"
});

$.getJSON('http://whateverorigin.org/get?url=' + 
    encodeURIComponent('http://google.com') + '&callback=?',
    function (data) {
        console.log("> ", data);

        //If the expected response is text/plain
        $("#viewer").html(data.contents);

        //If the expected response is JSON
        //var response = $.parseJSON(data.contents);
});


CORS-Proxy

Der CORS-Proxy ist ein einfacher node.js-Proxy, mit dem die CORS-Anforderung für jede Website aktiviert werden kann. Es ermöglicht Javascript-Code auf Ihrer Site, auf Ressourcen in anderen Domänen zuzugreifen, die normalerweise aufgrund der Richtlinie mit demselben Ursprung blockiert würden.

Wie funktioniert es? CORS Proxy nutzt die Cross-Origin Resource Sharing, eine Funktion, die zusammen mit HTML 5 hinzugefügt wurde. Server können festlegen, dass Browser anderen Websites erlauben sollen, von ihnen gehostete Ressourcen anzufordern. CORS-Proxy ist einfach ein HTTP-Proxy, der Antworten mit der Aufschrift "Jeder kann dies anfordern" einen Header hinzufügt.

Dies ist ein weiterer Weg, um das Ziel zu erreichen (siehe www.corsproxy.com ). Alles was Sie tun müssen, ist http: // und www zu entfernen. von der URL, für die ein Proxy erstellt wird, und stellen Sie die URL mit voranwww.corsproxy.com/

$.get(
    'http://www.corsproxy.com/' +
    'en.wikipedia.org/wiki/Cross-origin_resource_sharing',
    function (response) {
        console.log("> ", response);
        $("#viewer").html(response);
});


CORS-Proxy-Browser

Kürzlich habe ich dieses gefunden, es beinhaltet verschiedene sicherheitsorientierte Cross Origin Remote Sharing-Dienstprogramme. Aber es ist eine Blackbox mit Flash als Backend.

Sie können es hier in Aktion sehen: CORS-Proxy-Browser
Holen Sie sich den Quellcode auf GitHub: koto / cors-proxy-browser

Jherax
quelle
4
Sie können auch Ihre eigene Version von WhateverOrigin.org bereitstellen (oder den Code für Ihren eigenen Gebrauch
portieren
1
Bilder, CSS und externes Javascript können von einem anderen Ursprung aus referenziert werden. In der Antwort können Sie also die HTML-Zeichenfolge durchgehen und den
Quellcode
1
hi jherax Ich habe was auch immer ursprünglich verwendet, um eine HTML-Seite zu erhalten (nur so hat es bei mir funktioniert, habe yql, google usw. verwendet), aber nicht englische Zeichen sind seltsam. versucht, data.contents zu codieren, aber nicht geholfen
user217648
1
Hallo @Miru, da der Titel lautet: "Laden einer domänenübergreifenden HTML-Seite mit jQuery AJAX", antwortete ich auf den Titel mit einigen Beispielen, die einen Proxy zum Ausführen domänenübergreifender Anforderungen verwenden. Als Antwort auf den Wortlaut der Frage habe ich einige Links bereitgestellt, um domänenübergreifende Anforderungen mithilfe von JSONP mit YQL zu stellen. Ich lade Sie ein, die Links zu lesen, sie sind sehr nützlich.
Jherax
1
Endete mit der CORS Anywhere-Methode mit der $.ajaxPrefilterund es hat super funktioniert. Danke vielmals!
Joshua Pinter
24

Sie können Ajax-Cross-Origin als jQuery-Plugin verwenden. Mit diesem Plugin verwenden Sie jQuery.ajax()domänenübergreifend. Hierzu werden Google-Dienste verwendet:

Das AJAX Cross Origin-Plugin verwendet Google Apps Script als Proxy-jSON-Getter, bei dem jSONP nicht implementiert ist. Wenn Sie die Option crossOrigin auf true setzen, ersetzt das Plugin die ursprüngliche URL durch die Google Apps Script-Adresse und sendet sie als verschlüsselten URL-Parameter. Das Google Apps-Skript verwendet Google Server-Ressourcen, um die Remote-Daten abzurufen und als JSONP an den Client zurückzugeben.

Es ist sehr einfach zu bedienen:

    $.ajax({
        crossOrigin: true,
        url: url,
        success: function(data) {
            console.log(data);
        }
    });

Sie können hier mehr lesen: http://www.ajax-cross-origin.com/

Ninioe
quelle
21
Für mich hat dieses Plugin nie funktioniert. Auf Chrome macht es nichts.
Michael
Wie kann ich mich beim Server authentifizieren?
sttaq
funktioniert super! Die API, die ich verwende, unterstützt weder JSONP noch CORS. Dies ist also das einzige, was funktioniert hat. Vielen Dank!
JP Lew
Die crossOriginOption von jQuery trägt sicherlich nicht dazu bei, Richtlinien mit demselben Ursprung zu mildern. Ich würde diese Antwort löschen, wenn ich könnte
Phil
13

Wenn die externe Site JSONP oder CORS nicht unterstützt, können Sie nur einen Proxy verwenden.

Erstellen Sie auf Ihrem Server ein Skript, das diesen Inhalt anfordert, und verwenden Sie dann jQuery ajax, um das Skript auf Ihrem Server aufzurufen.

Kevin B.
quelle
5

Fügen Sie dies einfach in den Header Ihrer PHP-Seite ein und es funktioniert ohne API nicht:

header('Access-Control-Allow-Origin: *'); //allow everybody  

oder

header('Access-Control-Allow-Origin: http://codesheet.org'); //allow just one domain 

oder

$http_origin = $_SERVER['HTTP_ORIGIN'];  //allow multiple domains

$allowed_domains = array(
  'http://codesheet.org',
  'http://stackoverflow.com'
);

if (in_array($http_origin, $allowed_domains))
{  
    header("Access-Control-Allow-Origin: $http_origin");
}
studio-klik
quelle
Ich frage mich, woher $_SERVER['HTTP_ORIGIN']kommt. Ich konnte es nicht in der PHP-Dokumentation oder anderswo finden.
Zsolti
Hmm, es scheint, dass es nur mit AJAX-Anfragen gefüllt ist. Trotzdem danke für die Antwort.
Zsolti
0

Ich poste dies für den Fall, dass jemand das gleiche Problem hat, mit dem ich gerade konfrontiert bin. Ich habe einen Zebra-Thermodrucker, der mit dem ZebraNet-Druckserver ausgestattet ist und eine HTML-basierte Benutzeroberfläche zum Bearbeiten mehrerer Einstellungen, Anzeigen des aktuellen Status des Druckers usw. bietet. Ich muss den Status des angezeigten Druckers abrufen auf einer dieser HTML-Seiten, die vom ZebraNet-Server angeboten werden, und beispielsweise alert () eine Nachricht an den Benutzer im Browser. Dies bedeutet, dass ich diese HTML-Seite zuerst in Javascript erhalten muss. Obwohl sich der Drucker im LAN des PCs des Benutzers befindet, gilt diese Richtlinie für denselben Ursprungbleibt mir immer noch fest im Weg. Ich habe JSONP ausprobiert, aber der Server gibt HTML zurück und ich habe keine Möglichkeit gefunden, seine Funktionalität zu ändern (wenn ich könnte, hätte ich bereits den magischen Header Access-control-allow-origin gesetzt: *). Also habe ich beschlossen, eine kleine Konsolen-App in C # zu schreiben. Es muss als Admin ausgeführt werden, damit es ordnungsgemäß funktioniert. Andernfalls wird Folgendes ausgeführt: D eine Ausnahme. Hier ist ein Code:

// Create a listener.
        HttpListener listener = new HttpListener();
        // Add the prefixes.
        //foreach (string s in prefixes)
        //{
        //    listener.Prefixes.Add(s);
        //}
        listener.Prefixes.Add("http://*:1234/"); // accept connections from everywhere,
        //because the printer is accessible only within the LAN (no portforwarding)
        listener.Start();
        Console.WriteLine("Listening...");
        // Note: The GetContext method blocks while waiting for a request. 
        HttpListenerContext context;
        string urlForRequest = "";

        HttpWebRequest requestForPage = null;
        HttpWebResponse responseForPage = null;
        string responseForPageAsString = "";

        while (true)
        {
            context = listener.GetContext();
            HttpListenerRequest request = context.Request;
            urlForRequest = request.RawUrl.Substring(1, request.RawUrl.Length - 1); // remove the slash, which separates the portNumber from the arg sent
            Console.WriteLine(urlForRequest);

            //Request for the html page:
            requestForPage = (HttpWebRequest)WebRequest.Create(urlForRequest);
            responseForPage = (HttpWebResponse)requestForPage.GetResponse();
            responseForPageAsString = new StreamReader(responseForPage.GetResponseStream()).ReadToEnd();

            // Obtain a response object.
            HttpListenerResponse response = context.Response;
            // Send back the response.
            byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseForPageAsString);
            // Get a response stream and write the response to it.
            response.ContentLength64 = buffer.Length;
            response.AddHeader("Access-Control-Allow-Origin", "*"); // the magic header in action ;-D
            System.IO.Stream output = response.OutputStream;
            output.Write(buffer, 0, buffer.Length);
            // You must close the output stream.
            output.Close();
            //listener.Stop();

Der Benutzer muss lediglich diese Konsolen-App als Administrator ausführen. Ich weiß, dass es viel zu ... frustrierend und kompliziert ist, aber es ist eine Art Problemumgehung für das Domänenrichtlinienproblem, falls Sie den Server in keiner Weise ändern können.

edit: von js Ich mache einen einfachen Ajax-Aufruf:

$.ajax({
                type: 'POST',
                url: 'http://LAN_IP:1234/http://google.com',
                success: function (data) {
                    console.log("Success: " + data);
                },
                error: function (e) {
                    alert("Error: " + e);
                    console.log("Error: " + e);
                }
            });

Das HTML der angeforderten Seite wird zurückgegeben und in der Datenvariablen gespeichert .

user2177283
quelle
0

Um die Daten von einer externen Site zu erhalten, indem Sie einen lokalen Proxy verwenden, wie von jherax vorgeschlagen, können Sie eine PHP-Seite erstellen, die den Inhalt für Sie von der jeweiligen externen URL abruft, und dann eine Get-Anfrage an diese PHP-Seite senden.

var req = new XMLHttpRequest();
req.open('GET', 'http://localhost/get_url_content.php',false);
if(req.status == 200) {
   alert(req.responseText);
}

Als PHP-Proxy können Sie https://github.com/cowboy/php-simple-proxy verwenden

Nitigya Sharma
quelle
0

Ihr URLfunktioniert heutzutage nicht, aber Ihr Code kann mit dieser funktionierenden Lösung aktualisiert werden:

var url = "http://saskatchewan.univ-ubs.fr:8080/SASStoredProcess/do?_username=DARTIES3-2012&_password=P@ssw0rd&_program=%2FUtilisateurs%2FDARTIES3-2012%2FMon+dossier%2Fanalyse_dc&annee=2012&ind=V&_action=execute";

url = 'https://google.com'; // TEST URL

$.get("https://images"+~~(Math.random()*33)+"-focus-opensocial.googleusercontent.com/gadgets/proxy?container=none&url=" + encodeURI(url), function(data) {
    $('div.ajax-field').html(data);
});
<div class="ajax-field"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

350D
quelle
-2

Sie benötigen einen CORS-Proxy, der Ihre Anfrage von Ihrem Browser an den angeforderten Dienst mit den entsprechenden CORS-Headern weiterleitet . Eine Liste solcher Dienste finden Sie im Code-Snippet unten. Sie können auch das bereitgestellte Code-Snippet ausführen, um von Ihrem Standort aus einen Ping an solche Dienste zu senden.

$('li').each(function() {
  var self = this;
  ping($(this).text()).then(function(delta) {
    console.log($(self).text(), delta, ' ms');
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/jdfreder/pingjs/c2190a3649759f2bd8569a72ae2b597b2546c871/ping.js"></script>
<ul>
  <li>https://crossorigin.me/</li>
  <li>https://cors-anywhere.herokuapp.com/</li>
  <li>http://cors.io/</li>
  <li>https://cors.5apps.com/?uri=</li>
  <li>http://whateverorigin.org/get?url=</li>
  <li>https://anyorigin.com/get?url=</li>
  <li>http://corsproxy.nodester.com/?src=</li>
  <li>https://jsonp.afeld.me/?url=</li>
  <li>http://benalman.com/code/projects/php-simple-proxy/ba-simple-proxy.php?url=</li>
</ul>

galeksandrp
quelle
11
Dies beantwortet die Frage in keiner Weise.
0xc0de
@ 0xc0de Ich habe endlich eine Antwort geschrieben.
Galeksandrp
-7

Herausgefunden. Verwendet dies stattdessen.

$('.div_class').load('http://en.wikipedia.org/wiki/Cross-origin_resource_sharing #toctitle');
user3279865
quelle
Der dort verwendete Code ist irrelevant. Was zählt, sind die serverseitigen CORS-Header.
Quentin