クロスドメイン js フロントエンドの 8 つの実装ソリューション

クロスドメイン js フロントエンドの 8 つの実装ソリューション

同一オリジンポリシーの制限により、同じオリジンを満たすスクリプトのみがリソースを取得できます。これはネットワーク セキュリティの確保に役立ちますが、リソースの使用も制限されます。
では、クロスドメインを実現するにはどうすればよいでしょうか? クロスドメインを実現する方法をいくつか紹介します。

1. jsonp クロスドメイン

原則: スクリプト タグは、クロスドメインの影響を受けずに js ファイルを導入します。それだけでなく、src 属性を持つタグは同一オリジン ポリシーの影響を受けません。

この機能に基づいて、スクリプト タグの src 属性を通じてリソースを読み込み、src 属性が指すサーバー上に json 形式でデータを配置します。

スクリプトのsrcの読み込み状況が判断できず、データが取得できたかどうかわからないため、事前に処理関数を定義します。サーバーはデータの先頭にこの関数名を追加し、すべてのデータがロードされると、事前に定義した関数を呼び出します。このとき、関数に渡される実際のパラメータは、バックエンドから返されるデータです。

インデックス.html

<!DOCTYPE html>
<html lang="ja">
<ヘッド>
  <メタ文字セット="UTF-8">
  <title>ドキュメント</title>
</head>
<本文>
  <スクリプト>
    関数コールバック(データ) {
      アラート(データ.テスト);
    }
  </スクリプト>
  <script src="./jsonp.js"></script>
</本文>
</html>

jsonp.js

コールバック({"テスト": 0});

index.htmlにアクセスすると、ポップアップウィンドウに0が表示されます。
このソリューションの欠点は、get という 1 つのリクエストしか実装できないことです。

2. document.domain + iframe クロスドメイン

このソリューションは、メイン ドメインは同じだがサブドメインが異なるアプリケーション シナリオに限定されます。

たとえば、Baidu のメイン Web ページは www.baidu.com であり、zhidao.baidu.com や news.baidu.com などの Web サイトはメイン ドメイン www.baidu.com のサブドメインです。

実装原則: 両方のページは js を通じて document.domain を基本的なプライマリ ドメインとして設定し、同じドメインを実現して相互にリソースを操作できるようになります。

インデックス.html

<!DOCTYPE html>
<html lang="ja">
<ヘッド>
  <メタ文字セット="UTF-8">
  <title>ドキュメント</title>
</head>
<本文>
  <iframe src="https://mfaying.github.io/lesson/cross-origin/document-domain/child.html"></iframe>
  <スクリプト>
    ドキュメントのドメイン = 'mfaying.github.io';
    var t = '0';
  </スクリプト>
</本文>
</html>

子.html

<!DOCTYPE html>
<html lang="ja">
<ヘッド>
  <メタ文字セット="UTF-8">
  <title>ドキュメント</title>
</head>
<本文>
  <スクリプト>
    ドキュメントのドメイン = 'mfaying.github.io';
    アラート(window.parent.t);
  </スクリプト>
</本文>
</html>

3. location.hash + iframe クロスドメイン

親ページで iframe の src 属性が変更されると、location.hash の値は変更されますが、ページは更新されません (同じページのままです)。値は子ページの window.localtion.hash を通じて取得できます。

インデックス.html

<!DOCTYPE html>
<html lang="ja">
<ヘッド>
  <メタ文字セット="UTF-8">
  <title>ドキュメント</title>
</head>
<本文>
  <iframe src="child.html#" style="display: none;"></iframe>
  <スクリプト>
    var oIf = document.getElementsByTagName('iframe')[0];
    document.addEventListener('クリック', 関数() {
      oIf.src += '0';
    }、 間違い);
  </スクリプト>
</本文>
</html>

子.html

<!DOCTYPE html>
<html lang="ja">
<ヘッド>
  <メタ文字セット="UTF-8">
  <title>ドキュメント</title>
</head>
<本文>
  <スクリプト>
    window.onhashchange = 関数() {
      アラート(window.location.hash.slice(1));
    }
  </スクリプト>
</本文>
</html>

index.htmlページのポップアップウィンドウをクリックすると、0が表示されます。

4. window.name + iframe クロスドメイン

原則: window.name プロパティは、異なるページ (異なるドメイン名でも) を読み込んだ後も存在し、name にはより長い値 (2 MB) を割り当てることができます。
iframe と異なるオリジンのページでウィンドウの name 属性を設定し、iframe を同じオリジンのページへポイントします。このとき、ウィンドウの name 属性値は変更されないため、クロスドメイン データの取得が実現されます。

./親/インデックス.html

<!DOCTYPE html>
<html lang="ja">
<ヘッド>
  <メタ文字セット="UTF-8">
  <title>ドキュメント</title>
</head>
<本文>
  <スクリプト>
    var oIf = document.createElement('iframe');
    oIf.src = 'https://mfaying.github.io/lesson/cross-origin/window-name/child.html';
    var 状態 = 0;
    oIf.onload = 関数(){
      状態 === 0 の場合
        状態 = 1;
        oIf.src = 'https://mfaying.github.io/lesson/cross-origin/window-name/parent/proxy.html';
      } それ以外 {
        アラート(JSON.parse(oIf.contentWindow.name).test);
      }
    }
    document.body.appendChild(oIf);
  </スクリプト>
</本文>
</html>

./親/プロキシ.html

空のファイル。プロキシ ページとしてのみ使用されます。

./child.html

<!DOCTYPE html>
<html lang="ja">
<ヘッド>
  <メタ文字セット="UTF-8">
  <title>ドキュメント</title>
</head>
<本文>
  <スクリプト>
    ウィンドウ名 = '{"テスト": 0}'
  </スクリプト>
</本文>
</html>

5. postMessage クロスドメイン

postMessage は HTML5 で提案されたもので、ドキュメント間のメッセージ送信を実現できます。
使用法
getMessageHTML.postMessage(データ、オリジン);
data: HTML5 仕様でサポートされている任意の基本型またはコピー可能なオブジェクトですが、一部のブラウザは文字列のみをサポートしているため、パラメータを渡すときは JSON.stringify() シリアル化を使用するのが最適です。

origin: プロトコル + ホスト + ポート番号。"*" に設定することもできます。これは、任意のウィンドウに渡すことができることを意味します。現在のウィンドウと同じ origin を指定する場合は、"/" に設定します。
getMessageHTML は、情報を受け取るページへの参照です。これは、iframe の contentWindow プロパティ、window.open の戻り値、または名前または添え字を介して window.frames から取得された値になります。

インデックス.html

<!DOCTYPE html>
<html lang="ja">
<ヘッド>
  <メタ文字セット="UTF-8">
  <title>ドキュメント</title>
</head>
<本文>
    <iframe id='ifr' src='./child.html' style="display: none;"></iframe>
    <button id='btn'>クリック</button>
    <スクリプト>
      var btn = document.getElementById('btn');
      btn.addEventListener('click', 関数() {
        var ifr = document.getElementById('ifr');
        ifr.contentWindow.postMessage(0, '*');
      }、 間違い);
    </スクリプト>
</本文>
</html>

子.html

<!DOCTYPE html>
<html lang="ja">
<ヘッド>
  <メタ文字セット="UTF-8">
  <title>ドキュメント</title>
</head>
<本文>
    <スクリプト>
      window.addEventListener('メッセージ', 関数(イベント){
        アラート(イベント.データ);
      }、 間違い);
    </スクリプト>
</本文>
</html>

index.html ページのボタンをクリックすると、ポップアップ ウィンドウに 0 が表示されます。

6. クロスオリジンリソース共有 (CORS)

クロスドメインリクエストは、サーバー側で Access-Control-Allow-Origin を設定することで実装できます。Cookie リクエストの場合は、フロントエンドとバックエンドの両方を設定する必要があります。
同一オリジン ポリシーの制限により、読み取られる Cookie は、現在のページの Cookie ではなく、クロスドメイン リクエスト インターフェイスが配置されているドメインの Cookie になります。
CORS は現在主流のクロスドメイン ソリューションです。

ネイティブNode.js実装

インデックス.html

<!DOCTYPE html>
<html lang="ja">
<ヘッド>
  <メタ文字セット="UTF-8">
  <title>ドキュメント</title>
  <スクリプト
    src="https://code.jquery.com/jquery-3.4.1.min.js"
    整合性="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
    クロスオリジン="匿名"></script>
</head>
<本文>
  <スクリプト>
    $.get('http://localhost:8080', 関数(データ) {
      アラート(データ);
    });
  </スクリプト>
</本文>
</html>

サーバー.js

var http = require('http');
var server = http.createServer();

server.on('request', 関数(req, res) {
  res.writeHead(200, {
    'Access-Control-Allow-Credentials': 'true', // バックエンドはクッキーの送信を許可します
    'Access-Control-Allow-Origin': 'https://mfaying.github.io', // アクセスが許可されるドメイン (プロトコル + ドメイン名 + ポート)
    'Set-Cookie': 'key=1;Path=/;Domain=mfaying.github.io;HttpOnly' // HttpOnly: スクリプトはクッキーを読み取ることができません
  });

  res.write(JSON.stringify(req.method));
  res.end();
});

server.listen('8080');
console.log('サーバーはポート8080で実行されています...');

koa と koa2-cors ミドルウェア実装の組み合わせ

インデックス.html

<!DOCTYPE html>
<html lang="ja">
<ヘッド>
  <メタ文字セット="UTF-8">
  <title>ドキュメント</title>
  <スクリプト
    src="https://code.jquery.com/jquery-3.4.1.min.js"
    整合性="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
    クロスオリジン="匿名"></script>
</head>
<本文>
  <スクリプト>
    $.get('http://localhost:8080', 関数(データ) {
      アラート(データ);
    });
  </スクリプト>
</本文>
</html>

サーバー.js

var koa = require('koa');
var router = require('koa-router')();
koa2-cors を require します。

var app = new koa();

app.use(cors({
  原点: 関数 (ctx) {
    ctx.url === '/test'の場合{
      false を返します。
    }
    戻る '*';
  },
  公開ヘッダー: ['WWW-認証', 'サーバー認証'],
  最大年齢: 5,
  資格情報: true、
  許可メソッド: ['GET', 'POST', 'DELETE'],
  allowHeaders: ['Content-Type', 'Authorization', 'Accept'],
}))

router.get('/', 非同期関数(ctx) {
  ctx.body = "0";
});

アプリ
  .use(ルーター.routes())
  .use(router.allowedMethods());

アプリをリッスンする(3000);
console.log('サーバーはポート3000でリッスンしています');

7. WebSocketプロトコルのクロスドメイン

WebSocket プロトコルは HTML5 の新しいプロトコルです。ブラウザとサーバー間の全二重通信を実現し、クロスドメイン通信を可能にするため、サーバー側プッシュ技術の優れた実装となります。

フロントエンドコード:

<!DOCTYPE html>
<html lang="ja">
<ヘッド>
  <メタ文字セット="UTF-8">
  <meta name="viewport" content="width=デバイス幅、初期スケール=1.0">
  <meta http-equiv="X-UA-compatible" content="ie=edge">
  <title>ドキュメント</title>
</head>
<本文>
  <スクリプト>
    var ws = new WebSocket('ws://localhost:8080/', 'echo-protocol');
    // 接続を確立することによってトリガーされるイベント ws.onopen = function () {
      var データ = { "テスト": 1 };
      ws.send(JSON.stringify(data)); // バックエンドにデータを送信できます};
 
    // メッセージを受信するためのコールバックメソッド ws.onmessage = function (event) {
      アラート(JSON.parse(event.data).test);
    }
 
    // 切断トリガーイベント ws.onclose = function () {
      conosle.log('閉じる');
    };
  </スクリプト>
</本文>
</html>

サーバー.js

var WebSocketServer = require('websocket').server;
var http = require('http');
 
var server = http.createServer(function(リクエスト, レスポンス) {
  レスポンス.writeHead(404);
  レスポンスの終了();
});
server.listen(8080, 関数() {
  console.log('サーバーはポート8080でリッスンしています');
});
 
wsServer = 新しいWebSocketServer({
    httpServer: サーバー、
    自動受け入れ接続: 偽
});
 
関数 originIsAllowed(origin) {
  true を返します。
}
 
wsServer.on('リクエスト', 関数(リクエスト) {
    リクエストのオリジンが許可されている場合
      リクエストを拒否します。
      console.log('origin ' + request.origin + ' からの接続が拒否されました。');
      戻る;
    }
    
    var connection = request.accept('echo-protocol', request.origin);
    console.log('接続が受け入れられました。');
    接続.on('メッセージ', 関数(メッセージ) {
      メッセージタイプ === 'utf8' の場合 {
        定数 reqData = JSON.parse(message.utf8Data);
        要求データ.テスト -= 1;
        接続時にUTFを送信します(JSON.stringify(reqData));
      }
    });
    接続.on('close', 関数() {
      コンソールログ('閉じる');
    });
});

8. nginx プロキシ クロスドメイン

原則: 同一オリジン ポリシーはブラウザのセキュリティ ポリシーであり、HTTP プロトコルの一部ではありません。サーバー側は HTTP プロトコルのみを使用して HTTP インターフェイスを呼び出すため、交差の問題は発生しません。

実装: nginx を使用してプロキシ サーバー (ドメイン名は test1 と同じですが、ポートは異なります) をジャンプ サーバーとして構成し、リバース プロキシを使用して test2 インターフェイスにアクセスします。また、Cookie 内のテスト情報を変更して、現在のドメイン Cookie の書き込みを容易にし、クロスドメイン ログインを実現することもできます。
nginx の具体的な構成:

#プロキシサーバー{
    聞く 81;
    サーバー名 www.test1.com;

    位置 / {
        proxy_pass http://www.test2.com:8080; #リバースプロキシ proxy_cookie_test www.test2.com www.test1.com; #Cookie インデックスのドメイン名を変更します index.html index.htm;

        add_header Access-Control-Allow-Origin http://www.test1.com; #フロントエンドがクッキーなしでドメインを通過するだけの場合は、*
        add_header アクセス制御許可資格情報が true である;
    }
}

これで、js フロントエンドを使用したクロスドメイン ソリューションの 8 つの実装ソリューションに関するこの記事は終了です。より関連性の高い js クロスドメイン コンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後も 123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • jsonpを使用してクロスドメインの問題を完全に解決する
  • js クロスドメイン リクエスト データの 3 つの一般的な方法
  • クロスドメインの問題を解決するための js フロントエンドの 8 つのソリューション (最新かつ最も完全)
  • Javascript クロスドメイン アクセス ソリューション
  • js iframe のクロスドメインアクセス(同じプライマリドメイン/同じプライマリドメイン以外)について詳しく説明します
  • js のクロスドメイン問題に対処する 5 つの方法のまとめ
  • JSクロスドメインソリューション:CORSを使用してクロスドメインを実現する

<<:  Linuxシステムの入出力管理とvimの共通機能の詳細な説明

>>:  MySql 共通クエリコマンド操作リスト

推薦する

UCenter ホームサイトに統計コードを追加

UCenter Homeは、ComsenzがリリースしたSNSサイト構築システムです。最新バージョン...

Vue の動的コンポーネントと非同期コンポーネントの詳細な理解

1. 動的コンポーネント <!DOCTYPE html> <html> &l...

Vueはシンプルな虫眼鏡効果を実装します

この記事では、参考までに、簡単な虫眼鏡効果を実現するためのVueの具体的なコードを紹介します。具体的...

25 個の CSS フレームワーク、ツール、ソフトウェア、テンプレートを共有

スプライトカウダウンロード CSS リントダウンロード プレフィックスダウンロード 1140px C...

Linuxカーネルをコンパイルする方法

1. 必要なカーネルバージョンをダウンロードする2. オペレーティングシステムにアップロードする3....

ES6スプレッド演算子の使用例

目次スプレッド演算子とレスト演算子とは何ですか?配列スプレッド演算子残り演算子(コレクション関数)ス...

Docker+Jenkinsによる自動デプロイの実現方法

Code Cloud を使用して Git コード ストレージ ウェアハウスを構築するhttps://...

JavaScriptでシンプルなスクロールウィンドウを実装する

この記事では、スクロールウィンドウを実装するためのJavaScriptの具体的なコードを参考までに紹...

CSSのtranslate(-50%,-50%)は水平および垂直の中央揃え効果を実現します。

translate(-50%,-50%) 属性:中央に配置するには、長さと幅の 50% だけ上と左...

layui をベースにしたログインページの実装

この記事の例では、ログインページを実装するためのlayuiの具体的なコードを参考までに共有しています...

ウェブのさまざまなフロントエンド印刷方法: CSS はウェブページの印刷スタイルを制御します

CSS は Web ページの印刷スタイルを制御します。 CSS を使用して印刷スタイルを制御します。...

Vueは単一ファイルコンポーネントの完全なプロセス記録を実装します

目次序文単一ファイルコンポーネント基本概念シンプルなローダーコンポーネントコンテンツの解析コンポーネ...

ドラッグアンドドロップでVueユーザーインターフェースを生成する方法

目次序文1. 技術原理1.1 レイアウト1.2 コンポーネント1.3 ステータス1.4 イベント1....

Mysql 5.7.17 をインストールした後、MySQL にログインするチュートリアル

mysql-5.7.17 のインストールについては記事の下部で紹介されているので、参考にしてください...

Dockerを使用してサーバー上で複数のPHPバージョンを実行する

PHP7 がリリースされてからかなり時間が経ちますが、パフォーマンスが大幅に向上したことはよく知られ...