Heim > Betrieb und Instandhaltung > Nginx > Wie lassen sich domänenübergreifende Probleme lösen? Eine kurze Analyse gängiger Lösungen

Wie lassen sich domänenübergreifende Probleme lösen? Eine kurze Analyse gängiger Lösungen

青灯夜游
Freigeben: 2023-04-25 19:57:58
nach vorne
2187 Leute haben es durchsucht

Wie lassen sich domänenübergreifende Probleme lösen? Eine kurze Analyse gängiger Lösungen

Domänenübergreifend ist ein Szenario, das in der Entwicklung häufig vorkommt und auch eine häufig in Interviews diskutierte Frage ist. Die Beherrschung gängiger domänenübergreifender Lösungen und der dahinter stehenden Prinzipien kann nicht nur unsere Entwicklungseffizienz verbessern, sondern uns auch bei Vorstellungsgesprächen wohler machen.

Also Lassen Sie uns heute mit Ihnen über verschiedene gängige Methoden zur Lösung domänenübergreifender Probleme aus der Front-End-Perspektive sprechen.

Was ist domänenübergreifend?

Bevor wir über domänenübergreifend sprechen, werfen wir zunächst einen Blick auf die Zusammensetzung einer URL:

Die Zusammensetzung einer URL umfasst normalerweise Protokoll, Hostname, Portnummer und Pfad , Abfrageparameter und Anker Mehrere Teile.

Ein Beispiel für eine URL wird hier angezeigt:

https://www.example.com:8080/path/resource.html?page=1&sort=desc#header
Nach dem Login kopieren

Im obigen Beispiel:
● Das Protokoll ist HTTPS
● Der Hostname ist www.example.com
● Die Portnummer ist 8080
● Der Pfad ist /path /resource.html
● Der Abfrageparameter ist page=1&sort=desc
● Der Anker ist header

Die sogenannte Cross-Domain bedeutet, dass jeder Teil des Protokolls, des Hostnamens und der Portnummer in der Anforderungs-URL enthalten ist anders.

Am Beispiel der obigen URL gelten die folgenden Schreibmethoden als domänenübergreifend:

http://www.example.com:8080/    // 协议不同
https://www.example.a.com:8080/ // 主机名不同
https://www.example.com:8081/   // 端口号不同
Nach dem Login kopieren

Warum ist es domänenübergreifend? Tatsächlich ist das Auftreten domänenübergreifender Probleme begrenzt durch die Same-Origin-Richtlinie des Browsers.

Wenn browserseitige Skripte (JS-Dateien) auf Netzwerkressourcen in anderen Domänen zugreifen, treten domänenübergreifende Probleme auf.

所谓同源策略,其实是浏览器的一种安全机制,用于限制一个网页中的网络请求仅能够访问来自同一源(域名、协议和端口号均相同)的资源,主要目的是防止恶意网站通过脚本窃取其他网站的敏感数据,保障用户的隐私和安全。

So lösen Sie domänenübergreifende Probleme

Wie bereits erwähnt, wird das Auftreten domänenübergreifender Probleme durch die Same-Origin-Richtlinie des Browsers begrenzt, sodass sich die gängigen Lösungen zur Lösung domänenübergreifender Probleme tatsächlich um Browser drehen :

1. Proxyserver

In unserer üblichen Entwicklung ist die am häufigsten verwendete Lösung zur Lösung domänenübergreifender Probleme die Verwendung eines Proxyservers.

ProxyserverUm das domänenübergreifende Problem zu lösen, wird tatsächlich die Funktion erfasst, dass die Same-Origin-Richtlinie nur durch den Zugriff des Browsers auf den Server eingeschränkt ist und es keine Einschränkung für den Zugriff des Servers auf den Server gibt

Als Zwischenserver verfügt er über eine Anforderungsweiterleitungsfunktion

. Konkret läuft die vom Front-End-Ingenieur geschriebene Webseite auf einem durch Gerüste wie Webpack erstellten Proxyserver. Wenn die Front-End-Webseite eine Netzwerkanforderung im Browser initiiert, wird die Anforderung tatsächlich an den Proxyserver gesendet , und dann der Proxyserver Die Anforderung wird an den Zielserver weitergeleitet, und dann wird die vom Zielserver zurückgegebene Antwort an den Client weitergeleitet. Der Proxyserver spielt in diesem Prozess eine Relaisrolle und kann Anforderungen und Antworten ändern, filtern und abfangen, um bestimmte Funktionen zu erreichen.

Da die Front-End-Webseite auf dem Proxyserver ausgeführt wird, gibt es kein domänenübergreifendes Problem.

Wie leitet der Proxyserver Anforderungen in der Online- und Entwicklungsumgebung weiter?

1. Online-Umgebung

In der Online-Umgebung verwenden wir im Allgemeinen nginx als Reverse-Proxy, um die Front-End-Anfrage an die Zielschnittstelle weiterzuleiten.

nginx ist ein leichter Webserver mit hoher Parallelität, ereignisgesteuert, plattformübergreifend und kann sowohl unter Windows als auch unter Linux konfiguriert werden.

Die Hauptmethode, die es als Proxyserver verwendet, um domänenübergreifende Probleme in der Entwicklung zu lösen, besteht darin, den laufenden Port der Online-Front-End-URL abzuhören und die Anfrage dann weiterzuleiten, nachdem eine Anfrage mit einem speziellen Tag gefunden wurde

.

2. Entwicklungsumgebung

In der Entwicklungsumgebung wird der Kern der Lösung domänenübergreifender Probleme mithilfe von erreicht, unabhängig davon, ob es sich um ein Front-End-Projekt handelt, das mit Hilfe von Webpack, Vite oder einem anderen Gerüst erstellt wurde http-proxy-middleware middleware . Der Kern der http-proxy-middleware-Middleware ist eine weitere Kapselung von
http-proxy

. Hier ist ein Beispielcode, der http-proxy-middleware verwendet, um die Anforderungsweiterleitungsfunktion im Projekt zu implementieren:

const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = {
  server: {
    proxy: {
      // 将 /api/* 的请求代理到 http://localhost:3000/*
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true,
        pathRewrite: { '^/api': '/' }
      }
    }
  }
};
Nach dem Login kopieren

Dannkönnen wir den nativen Knoten selbst verwenden und die http-Proxy-Bibliothek verwenden, um eine Anforderungsweiterleitung zu erstellen Funktion Proxyserver Demo, interessierte Freunde können es selbst testen und spielen :

1. Zuerst müssen Sie einen leeren Ordner (auf Englisch benannt) als Projektordner erstellen und dann

npm init -y

verwenden Befehl zum Installieren des Projekts. Projekt auf Knoten aktualisiert:

npm init -y
Nach dem Login kopieren
2. Erstellen Sie dann eine

index.html-Datei

im Stammverzeichnis des Projekts, um domänenübergreifende Anforderungen zu initiieren:

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>请求转发测试</title>
</head>

<body>
    <h1>请求转发测试</h1>
    <p id="message"></p>
    <script>
        fetch(&#39;/api/login&#39;)
            .then(response => response.text())
            .then(data => {
                document.getElementById(&#39;message&#39;).textContent = data;
            });
    </script>
</body>

</html>
Nach dem Login kopieren
3. Erstellen Sie dann eine neue

Index im Projektstammverzeichnis .js-Datei

, um serverseitigen Code zu schreiben. Die Datei index.js ist die Kerndatei für die Implementierung eines Proxyservers mit Anforderungsweiterleitungsfunktion.

const http = require(&#39;http&#39;);
const httpProxy = require(&#39;http-proxy&#39;);
const fs = require(&#39;fs&#39;);
const path = require(&#39;path&#39;);

// 创建代理服务器实例
const proxy = httpProxy.createProxyServer({});

// 创建HTTP服务器
const server = http.createServer((req, res) => {
    if (req.url === &#39;/&#39; || req.url.endsWith(&#39;.html&#39;)) {
        // 读取HTML文件
        const filename = path.join(__dirname, &#39;index.html&#39;);
        fs.readFile(filename, &#39;utf8&#39;, (err, data) => {
            if (err) {
                res.writeHead(500);
                res.end(&#39;Error reading HTML file&#39;);
            } else {
                res.writeHead(200, { &#39;Content-Type&#39;: &#39;text/html&#39; });
                res.end(data);
            }
        });
    } else if (req.url.startsWith(&#39;/api&#39;)) {
        // 重写路径,替换跨域关键词
        req.url = req.url.replace(/^\/api/, &#39;&#39;);
        // 将请求转发至目标服务器
        proxy.web(req, res, {
            target: &#39;http://localhost:3000/&#39;,
            changeOrigin: true,
        });    
    }
});

// 监听端口
server.listen(8080, () => {
    console.log(&#39;Server started on port 8080&#39;);
});
Nach dem Login kopieren

4. Dann schreiben Sie den Inhalt der

target.js-Datei

des Zielservers, um den domänenübergreifenden Zugriff zu testen:

const http = require(&#39;http&#39;);

const server = http.createServer((req, res) => {
    if (req.url.startsWith(&#39;/login&#39;)) {
        res.writeHead(200, { &#39;Content-Type&#39;: &#39;text/plain&#39; });
        res.end(&#39;我是localhost主机3000端口下的方法,恭喜你访问成功!&#39;);
    } else {
        res.writeHead(200, { &#39;Content-Type&#39;: &#39;text/plain&#39; });
        res.end(&#39;Hello, world!&#39;);
    }
});

server.listen(3000, () => {
    console.log(&#39;Target server is listening on port:3000&#39;);
})
Nach dem Login kopieren

5. 打开终端,输入启动目标服务器的命令:

node ./target.js //项目根目录下执行
Nach dem Login kopieren

6. 再开一个终端启动代理服务器,等待浏览器端发起请求就可以啦:

node ./index.js //项目根目录下执行
Nach dem Login kopieren

7. 最后在浏览器里访问http://localhost:8080, 打开控制台即可查看效果:

可以发现,浏览器network模块的网络请求确实是访问的8080端口的方法,但是我们的服务器默默的做了请求转发的功能,并将请求转发获取到的内容返回到了前端页面上。

其实http-proxy是对node内置库http的进一步封装,网络请求的核心部分还是使用http创建一个服务器对象去访问的。感兴趣的同学可以再读读http-proxy的源码~

除了代理服务器这种绕过浏览器同源策略的解决方式外,从前端的角度解决跨域问题还有如下一些常见的方法:

1.借助JSONP

JSONP的原理是通过动态创建

Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage