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.
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/ // 端口号不同
Wenn browserseitige Skripte (JS-Dateien) auf Netzwerkressourcen in anderen Domänen zugreifen, treten domänenübergreifende Probleme auf.
所谓同源策略,其实是浏览器的一种安全机制,用于限制一个网页中的网络请求仅能够访问来自同一源(域名、协议和端口号均相同)的资源,主要目的是防止恶意网站通过脚本窃取其他网站的敏感数据,保障用户的隐私和安全。
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-Umgebungnginx 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
. 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
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('/api/login')
.then(response => response.text())
.then(data => {
document.getElementById('message').textContent = data;
});
</script>
</body>
</html>
, um serverseitigen Code zu schreiben. Die Datei index.js ist die Kerndatei für die Implementierung eines Proxyservers mit Anforderungsweiterleitungsfunktion.
const http = require('http'); const httpProxy = require('http-proxy'); const fs = require('fs'); const path = require('path'); // 创建代理服务器实例 const proxy = httpProxy.createProxyServer({}); // 创建HTTP服务器 const server = http.createServer((req, res) => { if (req.url === '/' || req.url.endsWith('.html')) { // 读取HTML文件 const filename = path.join(__dirname, 'index.html'); fs.readFile(filename, 'utf8', (err, data) => { if (err) { res.writeHead(500); res.end('Error reading HTML file'); } else { res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(data); } }); } else if (req.url.startsWith('/api')) { // 重写路径,替换跨域关键词 req.url = req.url.replace(/^\/api/, ''); // 将请求转发至目标服务器 proxy.web(req, res, { target: 'http://localhost:3000/', changeOrigin: true, }); } }); // 监听端口 server.listen(8080, () => { console.log('Server started on port 8080'); });
des Zielservers, um den domänenübergreifenden Zugriff zu testen: 5. 打开终端,输入启动目标服务器的命令: 6. 再开一个终端启动代理服务器,等待浏览器端发起请求就可以啦: 7. 最后在浏览器里访问http://localhost:8080, 打开控制台即可查看效果: 可以发现,浏览器network模块的网络请求确实是访问的8080端口的方法,但是我们的服务器默默的做了请求转发的功能,并将请求转发获取到的内容返回到了前端页面上。 其实http-proxy是对node内置库http的进一步封装,网络请求的核心部分还是使用http创建一个服务器对象去访问的。感兴趣的同学可以再读读http-proxy的源码~ 除了代理服务器这种绕过浏览器同源策略的解决方式外,从前端的角度解决跨域问题还有如下一些常见的方法: JSONP的原理是通过动态创建
const http = require('http');
const server = http.createServer((req, res) => {
if (req.url.startsWith('/login')) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('我是localhost主机3000端口下的方法,恭喜你访问成功!');
} else {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello, world!');
}
});
server.listen(3000, () => {
console.log('Target server is listening on port:3000');
})
node ./target.js //项目根目录下执行
node ./index.js //项目根目录下执行
1.借助JSONP