Heim  >  Artikel  >  Web-Frontend  >  Die umfassendste Lösung für domänenübergreifendes Ajax

Die umfassendste Lösung für domänenübergreifendes Ajax

韦小宝
韦小宝Original
2018-03-08 16:00:341882Durchsuche

Als ich anfing, JavaScript zu lernen, wusste ich nicht, was Ajax-Cross-Domain ist, aber ich hörte oft einige große Leute über domänenübergreifende Ajax-Cross-Domain-Probleme reden. Es muss einige Klassenkameraden geben Ich mag es, also werfen wir heute einen Blick darauf, was genau Ajax-Cross-Domain ist und welche Methoden es gibt, um Ajax-Cross-Domain zu lösen!

Vorwort

In Bezug auf domänenübergreifend gibt es N-Typen, die sich nur auf domänenübergreifende Ajax-Anfragen konzentrieren. Die Domäne gehört nur zum Durchsuchen. Teil der „Same-Origin-Richtlinie“ des Servers, andere umfassen domänenübergreifende Cookies, domänenübergreifende Iframes, domänenübergreifende LocalStorage usw. (hier nicht vorgestellt). Der Inhalt lautet ungefähr wie folgt:

1. Was ist Ajax Cross-Domain

Prinzip

Leistung (organisiert einige Begegnungen, Probleme und Lösungen)

2. So lösen Sie Ajax domänenübergreifend

JSONP-Methode

CORS-Methode

Proxy-Anfragemethode

3. So analysieren Sie Ajax domänenübergreifend

Analyse der HTTP-Paketerfassung

Einige Beispiele

Was ist domänenübergreifendes Ajax? 🎜>Ajax hat ein domänenübergreifendes Fehlerproblem. Der Hauptgrund liegt im Surfen. Sie können sich auf

Browser Same Origin Policy und seine Umgehungsmethoden beziehen 🎜>

CORS-Anfrageprinzip

CORS ist ein W3C-Standard, der vollständige Name lautet „Cross-Origin-Ressource“. Teilen". Es ermöglicht dem Browser, XMLHttpRequest-Anfragen an Cross-Origin-Server zu stellen und überwindet so die Einschränkung, dass AJAX nur vom gleichen Ursprung aus verwendet werden kann.

Grundsätzlich haben alle aktuellen Browser den CORS-Standard implementiert. Tatsächlich basieren fast alle Browser-Ajax-Anfragen auf dem CORS-Mechanismus, aber Front-End-Entwickler kümmern sich möglicherweise nicht darum (also eigentlich hauptsächlich um die aktuelle CORS-Lösung). überlegt, wie das Backend implementiert werden soll). Bezüglich CORS wird dringend empfohlen,

Ausführliche Erklärung von CORS für die domänenübergreifende Ressourcenfreigabe

In zu lesen Darüber hinaus ist hier auch eine Implementierung zusammengestellt. Schematisch (vereinfachte Version):



Wie kann man feststellen, ob es sich um eine einfache Anfrage handelt?

Browser unterteilen CORS-Anfragen in zwei Kategorien: einfache Anfragen und nicht ganz so einfache Anfragen. Sofern die beiden folgenden Bedingungen gleichzeitig erfüllt sind, handelt es sich um eine einfache Anfrage. Die umfassendste Lösung für domänenübergreifendes Ajax1. Die Anforderungsmethode

ist eine der folgenden drei Methoden: HEAD, GET, POST

2. HTTP-Header-Informationen Überschreiten Sie nicht die folgenden Felder:

1. AkzeptierenAkzeptieren 2. Accept-Language

3. Inhalt-Sprache

4. Letzte-Ereignis-ID 5. Content-Type (beschränkt auf drei Werte application/x-www-form-urlencoded, multipart/form-data, text/plain)

Immer anders Wenn die beiden oben genannten Bedingungen erfüllt sind, handelt es sich um eine nicht einfache Anfrage.

Ajax-Cross-Domain-Leistung

Um ehrlich zu sein, habe ich einen Artikel zusammengestellt und ihn dann als Lösung verwendet, aber später habe ich das gefunden Es war immer noch Viele Leute wissen immer noch nicht wie. Wir haben keine andere Wahl, als es zu debuggen, was zeit- und arbeitsintensiv ist. Aber selbst wenn ich es analysiere, werde ich nur anhand der entsprechenden Leistung beurteilen, ob es domänenübergreifend ist, daher ist dies sehr wichtig.

Wenn bei einer Ajax-Anfrage ein domänenübergreifendes Phänomen vorliegt und dieses nicht behoben wird, tritt das folgende Verhalten auf: (Beachten Sie, dass es sich um eine Ajax-Anfrage handelt. Bitte sagen Sie nicht, warum http-Anfragen in Ordnung sind Bei Ajax ist dies jedoch nicht der Fall, da Ajax von domänenübergreifend begleitet wird, sodass nur eine HTTP-Anfrage ok nicht ausreicht.

Das erste Phänomen:Auf der angeforderten Ressource ist kein Header „Access-Control-Allow-Origin“ vorhanden undDie Antwort hatte den HTTP-Statuscode 404

Die umfassendste Lösung für domänenübergreifendes Ajax

Die Gründe für diese Situation sind wie folgt:

1 Diese Ajax-Anfrage ist „. Keine einfache Anfrage“, daher wird vor der Anfrage eine Preflight-Anfrage (OPTIONS) gesendet

2. Die serverseitige Hintergrundschnittstelle lässt keine OPTIONS-Anfragen zu, was dazu führt, dass die entsprechende Schnittstellenadresse nicht gefunden werden kann

Lösung: Das Backend erlaubt Optionsanfragen

Zweites Phänomen:Auf der angeforderten Ressource ist kein Header „Access-Control-Allow-Origin“ vorhandenundDie Die Antwort hatte den HTTP-Statuscode 405


Die umfassendste Lösung für domänenübergreifendes Ajax

Dieses Phänomen unterscheidet sich vom ersten. In diesem Fall lässt die Hintergrundmethode OPTIONS-Anfragen zu, aber einige Konfigurationsdateien (z. B. Sicherheitskonfiguration) blockieren OPTIONS-Anfragen, was dies verursacht Phänomen.

Lösung: Schließen Sie die entsprechende Sicherheitskonfiguration im Backend

Drittes Phänomen:Auf der angeforderten Ressource ist kein „Access-Control-Allow-Origin“-Header vorhanden , und Status 200

Die umfassendste Lösung für domänenübergreifendes Ajax

Dieses Phänomen unterscheidet sich vom ersten und zweiten darin In diesem Fall lässt der serverseitige Hintergrund OPTIONS-Anfragen zu, und die Schnittstelle lässt auch OPTIONS-Anfragen zu, es liegt jedoch eine Nichtübereinstimmung vor, wenn die Header übereinstimmen.

Zum Beispiel stimmt die Überprüfung des Ursprungsheaders nicht mit einigen Headern überein Wenn die Unterstützung fehlt (z. B. der allgemeine X-Requested-With-Header), sendet der Server die Antwort an das Front-End zurück. Nachdem das Front-End dies erkannt hat, löst es XHR.onerror aus, was dazu führt, dass Endkonsole meldet einen Fehler

Lösung: Das Backend fügt entsprechende Header-Unterstützung hinzu

Das vierte Phänomen: heade enthält mehrere Werte '*,*'

Die umfassendste Lösung für domänenübergreifendes Ajax

Das Symptom ist, dass die HTTP-Header-Informationen der Hintergrundantwort zwei Access-Control-Allow-Origin haben:*

Um ehrlich zu sein, tritt diese Art von Problem auf. Der Hauptgrund dafür ist, dass Personen, die eine domänenübergreifende Konfiguration durchführen, das Prinzip nicht verstehen, was zu wiederholten Konfigurationen führt, wie zum Beispiel:

1. Häufig wird im .net-Hintergrund angezeigt (normalerweise wird der Ursprung einmal in web.config und dann erneut im Code konfiguriert. Der Ursprung wird einmal manuell hinzugefügt (der Code legt beispielsweise die Rückgabe * manuell fest))

2. Wird häufig gesehen im .net-Hintergrund (Origin:* gleichzeitig in IIS und in der Webkonfiguration des Projekts festlegen)

Lösung (Eins-zu-Eins-Korrespondenz):

1. Es wird empfohlen, die im Code manuell hinzugefügten * zu löschen und nur die in der Projektkonfiguration zu verwenden

2 , es wird empfohlen, die Konfiguration* unter IIS zu löschen und nur die zu verwenden eine in der Projektkonfiguration

So lösen Sie domänenübergreifende Ajax-Lösungen

Allgemeine domänenübergreifende Ajax-Lösungen werden über JSONP oder gelöst CORS, wie folgt: (Beachten Sie, dass JSONP fast nicht mehr verwendet wird, verstehen Sie also einfach JSONP)

JSONP-Lösung Domänenübergreifende Probleme

jsonp ist eine relativ alte Lösung zur Lösung domänenübergreifender Probleme (in der Praxis nicht empfohlen). Hier finden Sie eine kurze Einführung (wenn Sie JSONP in tatsächlichen Projekten verwenden möchten, verwenden Sie im Allgemeinen JQ und andere Klassenbibliotheken, die JSONP kapseln, um Ajax zu erstellen). Anfragen)

Implementierungsprinzip

Der Grund, warum JSONP zur Lösung domänenübergreifender Probleme verwendet werden kann, liegt hauptsächlich daran, dass <script> verfügen über domänenübergreifende Funktionen, und JSONP nutzt dies, um dies zu erreichen. Das konkrete Prinzip ist in der Abbildung </script>

Die umfassendste Lösung für domänenübergreifendes Ajax

dargestellt

Implementierungsprozess

Die Implementierungsschritte von JSONP sind ungefähr wie folgt (siehe Artikel in der Quelle)

1. Die Client-Webseite fordert JSON vom Server an, indem sie ein < ;script>-Elementdaten, dieser Ansatz ist nicht durch die gleiche Ursprungsrichtlinie eingeschränkt

function addScriptTag(src) {
  var script = document.createElement(&#39;script&#39;);
  script.setAttribute("type","text/javascript");
  script.src = src;
  document.body.appendChild(script);
}

window.onload = function () {
  addScriptTag(&#39;http://example.com/ip?callback=foo&#39;);
}

function foo(data) {
  console.log(&#39;response data: &#39; + JSON.stringify(data));
};

Bei der Anforderung wird die Schnittstellenadresse als Quelle des erstellten Skript-Tags verwendet wird erstellt, der letzte Quellcode ist die Schnittstelle. Zurückgegebener Inhalt

2. Die entsprechende Schnittstelle des Servers fügt eine Funktionsumbruchschicht außerhalb des Rückgabeparameters hinzu

foo({
  "test": "testData"
});

3. Das von der angeforderte Skript Das <script>-Element wird direkt als Code ausgeführt. Zu diesem Zeitpunkt wird die Funktion sofort aufgerufen, solange der Browser die Funktion foo definiert. JSON-Daten als Parameter werden als <a href="http://www.php.cn/js/js-jsref-tutorial.html" target="_blank">JavaScript-Objekte und nicht als Zeichenfolgen behandelt, wodurch der Schritt der Verwendung von JSON.parse vermieden wird. </script>

Beachten Sie, dass es einen Unterschied zwischen der allgemeinen JSONP-Schnittstelle und den von der normalen Schnittstelle zurückgegebenen Daten gibt. Wenn die Schnittstelle JSONO-kompatibel sein soll, muss daher beurteilt werden, ob ein entsprechender Callback-Schlüsselwortparameter vorhanden ist . Wenn dies der Fall ist, handelt es sich um eine JSONP-Anfrage und es werden JSONP-Daten zurückgegeben JSONP kann nur eine „GET“-Anfrage sein und kann keine komplexeren POST- und anderen Anfragen ausführen. Wenn Sie also auf diese Situation stoßen, müssen Sie auf das folgende CORS zurückgreifen, um domänenübergreifende Probleme zu lösen (dies wurde also im Grunde genommen jetzt beseitigt).

CORS löst domänenübergreifende Probleme

Das Prinzip von CORS wurde oben vorgestellt. Hier wird hauptsächlich vorgestellt, wie das Backend aussehen sollte konfiguriert, um Probleme in tatsächlichen Projekten zu lösen (da eine große Anzahl von Projektpraktiken durch das Backend gelöst werden). Hier sind einige gängige Backend-Lösungen: PHP-Backend-Konfiguration

Die PHP-Backend-Konfiguration ist fast die einfachste aller Backends. Befolgen Sie einfach die folgenden Schritte: Schritt 1: Konfigurieren Sie das PHP-Backend, um domänenübergreifend zu ermöglichen

Schritt 2: Apache-Webserver domänenübergreifend konfigurieren (in httpd.conf)

Der ursprüngliche Code

<?php
header(&#39;Access-Control-Allow-Origin: *&#39;);
header(&#39;Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept&#39;);
//主要为跨域CORS配置的两大基本信息,Origin和headers
wurde in den folgenden Code geändert

<Directory />
    AllowOverride none
    Require all denied
</Directory>
Node.js-Hintergrundkonfiguration (Express-Framework)

<Directory />
    Options FollowSymLinks
    AllowOverride none
    Order deny,allow
    Allow from all
</Directory>

Das Backend von Node.js ist ebenfalls relativ einfach zu konfigurieren. Verwenden Sie einfach Express, um wie folgt zu konfigurieren:

JAVA-Hintergrundkonfiguration

app.all(&#39;*&#39;, function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "X-Requested-With");
    res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
    res.header("X-Powered-By", &#39; 3.2.1&#39;)
        //这段仅仅为了方便返回json而已
    res.header("Content-Type", "application/json;charset=utf-8");
    if(req.method == &#39;OPTIONS&#39;) {
        //让options请求快速返回
        res.sendStatus(200); 
    } else { 
        next(); 
    }
});

Die JAVA-Hintergrundkonfiguration muss nur die folgenden Schritte ausführen:Schritt eins: Besorgen Sie sich das abhängige JAR-PaketLaden Sie

cors-filter-1.7.jar

,

java-property-utils-1.9.jar

herunter 2 Legen Sie die Bibliotheksdatei im lib-Verzeichnis ab. (Platzieren Sie es unter webcontent/WEB-INF/lib/ des entsprechenden Projekts)

Schritt 2: Wenn das Projekt mit Maven erstellt wurde, fügen Sie bitte die folgenden Abhängigkeiten zu pom.xml hinzu: (Wenn Sie nicht Maven sind , bitte ignorieren) Die Version sollte die neueste stabile Version sein, CORSFilter

Schritt 3: CORS-Konfiguration zur Web.xml des Projekts hinzufügen ( App/ WEB-INF/web.xml)
<dependency>
    <groupId>com.thetransactioncompany</groupId>
    <artifactId>cors-filter</artifactId>
    <version>[ version ]</version>
</dependency>

Bitte beachten Sie, dass die obige Konfigurationsdatei vor web.xml platziert werden und als erster Filter vorhanden sein sollte (es können mehrere Filter vorhanden sein)

Schritt 4: Mögliche Fehler bei der Konfiguration des Sicherheitsmoduls (beachten Sie, dass einige Frameworks, z. B. private Frameworks des Unternehmens, über Sicherheitsmodule verfügen. Manchmal wirken sich diese Sicherheitsmodulkonfigurationen auf die domänenübergreifende Konfiguration aus. In diesem Fall können Sie versuchen, sie umzukehren zuerst ausschalten)

<!-- 跨域配置-->    
<filter>
        <!-- The CORS filter with parameters -->
        <filter-name>CORS</filter-name>
        <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
        
        <!-- Note: All parameters are options, if omitted the CORS 
             Filter will fall back to the respective default values.
          -->
        <init-param>
            <param-name>cors.allowGenericHttpRequests</param-name>
            <param-value>true</param-value>
        </init-param>
        
        <init-param>
            <param-name>cors.allowOrigin</param-name>
            <param-value>*</param-value>
        </init-param>
        
        <init-param>
            <param-name>cors.allowSubdomains</param-name>
            <param-value>false</param-value>
        </init-param>
        
        <init-param>
            <param-name>cors.supportedMethods</param-name>
            <param-value>GET, HEAD, POST, OPTIONS</param-value>
        </init-param>
        
        <init-param>
            <param-name>cors.supportedHeaders</param-name>
            <param-value>Accept, Origin, X-Requested-With, Content-Type, Last-Modified</param-value>
        </init-param>
        
        <init-param>
            <param-name>cors.exposedHeaders</param-name>
            <!--这里可以添加一些自己的暴露Headers   -->
            <param-value>X-Test-1, X-Test-2</param-value>
        </init-param>
        
        <init-param>
            <param-name>cors.supportsCredentials</param-name>
            <param-value>true</param-value>
        </init-param>
        
        <init-param>
            <param-name>cors.maxAge</param-name>
            <param-value>3600</param-value>
        </init-param>

    </filter>

    <filter-mapping>
        <!-- CORS Filter mapping -->
        <filter-name>CORS</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

JAVA Spring Boot-Konfiguration

20171230 Ergänzend Nur ​​einfache globale Konfigurationen auflisten

Erstellen Sie eine neue Konfiguration und fügen Sie dann die Konfigurationsanmerkung hinzu, um die Konfiguration erfolgreich durchzuführen

PS: Dieser Teil der Methode ist enthalten und wurde nicht persönlich geübt, aber basierend auf dem Feedback ist er theoretisch machbar

@Configuration
public class CorsConfig {

    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();        
        // 可以自行筛选
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");        
        return corsConfiguration;
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        
        source.registerCorsConfiguration("/**", buildConfig());        
        return new CorsFilter(source);  
    }
}

NET-Hintergrundkonfiguration

.NET-Hintergrundkonfiguration kann sich auf die folgenden Schritte beziehen:Schritt 1 : Website-KonfigurationÖffnen Sie die Systemsteuerung, wählen Sie „Verwaltungstools“, wählen Sie „IIS“ aus; klicken Sie mit der rechten Maustaste auf Ihre Website und wählen Sie „Durchsuchen“. Öffnen Sie mit Notepad die Datei „web.config“ und fügen Sie sie hinzu Starten Sie die Website gemäß den Konfigurationsinformationen neu

请注意,以上截图较老,如果配置仍然出问题,可以考虑增加更多的headers允许,比如:

"Access-Control-Allow-Headers":"X-Requested-With,Content-Type,Accept,Origin"

第二步:其它更多配置,如果第一步进行了后,仍然有跨域问题,可能是:

1、接口中有限制死一些请求类型(比如写死了POST等),这时候请去除限 制

2、接口中,重复配置了Origin:*,请去除即可

3、IIS服务器中,重复配置了Origin:*,请去除即可

代理请求方式解决接口跨域问题

注意,由于接口代理是有代价的,所以这个仅是开发过程中进行的。

与前面的方法不同,前面CORS是后端解决,而这个主要是前端对接口进行代理,也就是:

1、前端ajax请求的是本地接口

2、本地接口接收到请求后向实际的接口请求数据,然后再将信息返回给前端

3、一般用node.js即可代理

关于如何实现代理,这里就不重点描述了,方法和多,也不难,基本都是基于node.js的。

搜索关键字node.js,代理请求即可找到一大票的方案。

OPTIONS预检的优化

Access-Control-Max-Age:

这个头部加上后,可以缓存此次请求的秒数。

在这个时间范围内,所有同类型的请求都将不再发送预检请求而是直接使用此次返回的头作为判断依据。

非常有用,可以大幅优化请求次数

如何分析ajax跨域

上述已经介绍了跨域的原理以及如何解决,但实际过程中,发现仍然有很多人对照着类似的文档无法解决跨域问题,主要体现在,前端人员不知道什么时候是跨域问题造成的,什么时候不是,因此这里稍微介绍下如何分析一个请求是否跨域:

抓包请求数据

第一步当然是得知道我们的ajax请求发送了什么数据,接收了什么,做到这一步并不难,也不需要fiddler等工具,仅基于Chrome即可

1、Chrome浏览器打开对应发生ajax的页面,F12打开Dev Tools

2、发送ajax请求

3、右侧面板->NetWork->XHR,然后找到刚才的ajax请求,点进去

示例一(正常的ajax请求)

Die umfassendste Lösung für domänenübergreifendes Ajax

上述请求是一个正确的请求,为了方便,我把每一个头域的意思都表明了,我们可以清晰的看到,接口返回的响应头域中,包括了

Access-Control-Allow-Headers: X-Requested-With,Content-Type,Accept
Access-Control-Allow-Methods: Get,Post,Put,OPTIONS
Access-Control-Allow-Origin: *

所以浏览器接收到响应时,判断的是正确的请求,自然不会报错,成功的拿到了响应数据。

示例二(跨域错误的ajax请求)

为了方便,我们仍然拿上面的错误表现示例举例。

Die umfassendste Lösung für domänenübergreifendes Ajax

这个请求中,接口Allow里面没有包括OPTIONS,所以请求出现了跨域、

Die umfassendste Lösung für domänenübergreifendes Ajax

这个请求中,Access-Control-Allow-Origin: *出现了两次,导致了跨域配置没有正确配置,出现了错误。

更多跨域错误基本都是类似的,就是以上三样没有满足(Headers,Allow,Origin),这里不再一一赘述。

示例三(与跨域无关的ajax请求)

当然,也并不是所有的ajax请求错误都与跨域有关,所以请不要混淆,比如以下:

Die umfassendste Lösung für domänenübergreifendes Ajax

更多

基本上都是这样去分析一个ajax请求,通过Chrome就可以知道了发送了什么数据,收到了什么数据,然后再一一比对就知道问题何在了。

总结

跨域是一个老生常谈的话题,网上也有大量跨域的资料,并且有不少精品(比如阮一峰前辈的),但是身为一个前端人员不应该浅尝而止,故而才有了本文。


Das obige ist der detaillierte Inhalt vonDie umfassendste Lösung für domänenübergreifendes Ajax. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn