Heim  >  Artikel  >  Betrieb und Instandhaltung  >  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

青灯夜游
青灯夜游nach vorne
2023-04-25 19:57:582118Durchsuche

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

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/   // 端口号不同

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': '/' }
      }
    }
  }
};

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
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>
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;);
});

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;);
})

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

node ./target.js //项目根目录下执行

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

node ./index.js //项目根目录下执行

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

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

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

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

1.借助JSONP

JSONP的原理是通过动态创建3f1c4e4b6b16bbbd69b2ee476dc4f83a标签,向服务器发送请求并在请求URL中传递一个回调函数名(通常是在本地定义的函数名),服务器在返回的数据中将这个回调函数名和实际数据一起封装成一个JavaScript函数的调用,返回给客户端,客户端利用该回调函数对数据进行处理。

JSONP之所以能够跨域请求数据,是因为浏览器对于3f1c4e4b6b16bbbd69b2ee476dc4f83a标签的请求不会受到同源策略的限制。

需要注意的是,使用JSONP技术的前提是服务器需要支持JSONP的方式,即在返回的数据中包含回调函数名和实际数据的封装,否则客户端无法处理返回的数据。

此外,JSONP只支持GET请求,不支持POST等其他HTTP请求方式,因为3f1c4e4b6b16bbbd69b2ee476dc4f83a标签只支持GET请求。

因此JSONP这种方式在我们的开发中使用的场景不多。

2.使用CORS

CORS全称为Cross-Origin Resource Sharing,它通过HTTP头部信息告诉浏览器哪些跨域请求是被允许的,从而实现安全的跨域访问。

CORS解决跨域需要浏览器端和服务器端的配合。原理是在服务器端设置HTTP头部信息,告诉浏览器允许哪些源(域名、协议、端口)访问服务器上的资源,如果请求的源不在允许的列表中,则浏览器将拒绝访
问。

服务器可以通过设置Access-Control-Allow-OriginAccess-Control-Allow-HeadersAccess-Control-Allow-Methods等HTTP头部信息来控制跨域访问权限。

具体地,当浏览器发起跨域请求时,会先发送一个OPTIONS请求(预检请求),询问服务器是否允许该跨域请求。

服务器接收到该请求后,根据请求中的HTTP头部信息判断是否允许该请求。

如果允许,则返回相应的HTTP头部信息告知浏览器可以继续发送真正的跨域请求。如果不允许,则返回一个错误状态码,告诉浏览器该请求被拒绝。

预检请求时,请求头常见参数有

请求头
Origin 表示请求的源地址,即发起跨域请求的域名
Access-Control-Request-Method 表示实际请求采用的HTTP方法
Access-Control-Request-Headers 表示实际请求中所携带的额外请求头信息,比如自定义请求头等

预检请求时,响应头常见参数有

响应头
Access-Control-Allow-Origin *、origin...
Access-Control-Allow-Headers POST, GET, PUT, DELETE, OPTIONS
Access-Control-Allow-Methods Content-Type, Authorization..
Access-Control-Allow-Credentials true
Access-Control-Max-Age 86400

Zu beachten ist, dass Voraussetzung für die Nutzung von CORS ist, dass der Server relevante HTTP-Header-Informationen setzen muss und der Browser CORS unterstützt. Darüber hinaus unterstützt CORS nur moderne Browser und einige ältere Browser unterstützen CORS möglicherweise nicht.

3. Andere Lösungen

wie WebSocket, postMessage usw.

Zusammenfassung

In den letzten Jahren, mit der rasanten Entwicklung der Front-End- und Back-End-Technologie, unabhängig Die Entwicklung von Front-End und Back-End ist nach und nach zum Mainstream-Entwicklungsmodell geworden. Die Front-End- und Back-End-Programmierer müssen sich lediglich auf die Schnittstelle einigen, dann die entsprechenden Module unabhängig voneinander entwickeln und schließlich ein gemeinsames Debugging der Schnittstelle durchführen. Während des gemeinsamen Debugging-Prozesses der Schnittstelle ist die domänenübergreifende Entwicklung in der Entwicklungsumgebung ein Problem, das gelöst werden muss.

Nachdem das aktuelle Back-End-Projekt gepackt und in die Cloud verschoben wurde und die Front-End-Seite über die Online-Adresse auf die Back-End-Schnittstelle zugreift, Domainübergreifend in der Online-Umgebung ist ebenfalls ein Problem das muss gelöst werden.

Dieser Artikel beschreibt mehrere gängige domänenübergreifende Lösungen. Jede dieser Lösungen hat ihre eigenen Vor- und Nachteile. Sie können je nach tatsächlicher Situation eine geeignete Lösung auswählen, um die entsprechenden domänenübergreifenden Probleme zu lösen. ~

Empfohlenes Tutorial: Nginx-Tutorial

Das obige ist der detaillierte Inhalt vonWie lassen sich domänenübergreifende Probleme lösen? Eine kurze Analyse gängiger Lösungen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.cn. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen