クロスドメインの問題を解決するにはどうすればよいですか?一般的なソリューションの簡単な分析

青灯夜游
リリース: 2023-04-25 19:57:58
転載
2117 人が閲覧しました

クロスドメインの問題を解決するにはどうすればよいですか?一般的なソリューションの簡単な分析

クロスドメインは開発においてよく遭遇するシナリオであり、インタビューでもよく議論される質問でもあります。一般的なクロスドメイン ソリューションとその背後にある原則を習得すると、開発効率が向上するだけでなく、面接もより快適になります。

それでは今日は、フロントエンドの観点からクロスドメインの問題を解決するためのいくつかの一般的な方法についてお話しましょう。

#クロスドメインとは#クロスドメインについて話す前に、まず URL のコンポーネントを見てみましょう:

URL 構成の内容には、通常、

プロトコル、ホスト名、ポート番号、パス、クエリ パラメーター、およびアンカー

部分が含まれます。 URL の例を次に示します:

https://www.example.com:8080/path/resource.html?page=1&sort=desc#header
ログイン後にコピー

上の例:

# プロトコルは HTTPS

# ホスト名は www.example.com
● ポート番号は 8080
# パスは /path/resource.html
#● クエリ パラメータは page=1&sort=desc
#● アンカー ポイントは header

※いわゆるクロスドメインとは、リクエストURL内のプロトコル、ホスト名、ポート番号のいずれかの部分が異なることを指します。

上記の URL を例に挙げると、次のような記述方法がクロスドメインとみなされます。

http://www.example.com:8080/    // 协议不同
https://www.example.a.com:8080/ // 主机名不同
https://www.example.com:8081/   // 端口号不同
ログイン後にコピー

なぜクロスドメインなのか

実際には クロスドメインの問題の発生は、ブラウザの同一生成元ポリシー

によって制限されています。

いわゆる同一オリジン ポリシーは、実際にはブラウザのセキュリティ メカニズムであり、Web ページ内のネットワーク リクエストを制限して、同じソース (ドメイン名、プロトコルとポート番号は同じです)リソースの主な目的は、悪意のある Web サイトがスクリプトを通じて他の Web サイトから機密データを盗むのを防ぎ、ユーザーのプライバシーとセキュリティを保護することです。

ブラウザ側のスクリプト (js ファイル) が他のドメインのネットワーク リソースにアクセスすると、クロスドメインの問題が発生します。

クロスドメインの問題を解決する方法

前述したように、クロスドメインの問題の発生はブラウザの同一オリジン ポリシーによって制限されているため、一般的な解決策は次のとおりです。クロスドメインの問題 解決策は実際にはブラウザを中心に展開します:

1. プロキシ サーバー

通常の開発では、クロスドメインの問題を解決するために が最も一般的に使用されます。ドメインの問題 解決策は、プロキシ サーバー

を使用することです。

プロキシサーバー

クロスドメイン問題を解決するために、同一オリジンポリシーはサーバーにアクセスするブラウザのみに限定されており、サーバーにアクセスするブラウザには制限がないという特徴を実際に把握しています。サーバーにアクセスするサーバー

仲介としてサーバーはリクエスト転送機能を持っています 具体的には、フロントエンドエンジニアが書いたWebページは、webpackなどのスキャフォールディングで構築されたプロキシサーバー上で動作し、フロントエンドWebページがブラウザ上でネットワークリクエストを開始すると、実際にリクエストが送信されます。プロキシ サーバーに送信すると、プロキシ サーバーはリクエストをターゲット サーバーに転送し、ターゲット サーバーから返された応答をクライアントに転送します。

プロキシ サーバーは、このプロセスで中継の役割を果たし、リクエストと応答を変更、フィルタリング、インターセプトして、特定の機能を実現します。

フロントエンド Web ページはプロキシ サーバー上で実行されるため、クロスドメインの問題は発生しません。

それでは、プロキシ サーバーはオンライン環境や開発環境でどのようにリクエストを転送するのでしょうか?

1. オンライン環境

オンライン環境では、通常、転送されたフロントエンド リクエストを転送するリバース プロキシとして nginx
を使用します。ターゲットインターフェイス。

nginx は軽量で同時実行性の高い Web サーバーであり、イベント駆動型のクロスプラットフォームであり、ウィンドウと Linux の両方で構成できます。

開発中のクロスドメインの問題を解決するプロキシ サーバーとして機能する主な方法は、オンライン フロントエンド URL の実行ポートをリッスンし、リクエストが発生した後にリクエストを転送することです。特別なタグ

が含まれています。

2. 開発環境

開発環境では、webpack を使用して構築されたフロントエンド プロジェクトであっても、vite またはその他のスキャフォールディングを使用して構築されたフロントエンド プロジェクトであっても、コアクロスドメインの問題の解決は、http-proxy-middleware ミドルウェア
の助けを借りて実装されます。 http-proxy-middleware ミドルウェアの中核は、

http-proxy をさらにカプセル化したものです。 これは、http-proxy-middleware

を使用してプロジェクトにリクエスト転送機能を実装するサンプル コードです:

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

module.exports = {
  server: {
    proxy: {
      // 将 /api/* 的请求代理到 http://localhost:3000/*
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true,
        pathRewrite: { '^/api': '/' }
      }
    }
  }
};
ログイン後にコピー
これで、 ネイティブ ノードを使用できるようになります。 , http-proxy ライブラリを使用してプロキシ サーバーを構築します。 リクエスト転送機能を備えたデモ。興味のある友達は自分でテストしてプレイできます。

:

1.

まず、空のフォルダー (英語名) をプロジェクト フォルダーとして使用し、

npm init -y コマンドを使用して、プロジェクトをノード プロジェクト

npm init -y
ログイン後にコピー
2 にアップグレードします。

次に、プロジェクトのルート ディレクトリに

index.html ファイル を作成して、クロスドメイン リクエストを開始します。

<!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.

次に、新しい

を作成します。プロジェクトのルート ディレクトリの .js ファイル にインデックスを付けて、サーバー側のコードを記述します。 index.js ファイルは、リクエスト転送機能を備えたプロキシ サーバーを実装するためのコア ファイルです。

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.

次に、クロスドメイン アクセスをテストするためにターゲット サーバーのコンテンツを書き込みます

target.js ファイル:

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的原理是通过动态创建

人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート