クロスドメイン問題#
問題の説明#
ブラウザはクロスサイトリクエストフォージェリ攻撃を防ぐために、同一生成元ポリシーを設定しています。フロントエンドのローカル開発の URL はほとんどが「http+localhost + ポート」であり、これによりクロスドメイン、クッキーの植え付け、外部サービスの呼び出しには実際のドメイン名が必要になる問題が発生します。
同一生成元ポリシーとは、2 つの生成元が相互に同一であることを指します。言い換えれば、プロトコル、ドメイン名、ポートがすべて一致している場合にのみ、相互に通信できるということです。これはリクエストの安全性を確保し、悪意のある攻撃を減らすためです。
クッキーの植え付け問題 -- フロントエンドとバックエンドの認証がクッキーに関与する場合、localhost のようなドメイン名がクッキーの植え付けに影響を与えます。ブラウザがクッキーを正しく植え付けるかどうかは、ドメインの影響を受けます。
外部サービスの呼び出しには実際のドメイン名が必要です。プロジェクトが外部サービスを呼び出す際には、しばしば完全な実際のドメイン名が必要です。例えば、WeChat ログインの場合です。この時、ローカル開発には完全な実際のドメイン名がないため、ローカルでの調整ができません。
同一生成元を検証するために、ブラウザはすべてのリクエストに特別なリクエストを付加してドメイン情報受信サーバーに送信します。サーバーが返すレスポンスには、Access-Control-Allow-Origin
というキーを含むヘッダーが付加され、どのような生成元がサーバーのリソースにアクセスできるかを示します。通常、2 つのモードに分かれます。値が * の場合、サーバーは任意の生成元が自分のリソースにアクセスすることを許可します。もう 1 つのモードは、指定された生成元の権限でアクセスすることです。
フロントエンド - 【訳】CORS エラーを解決する 3 つの方法と Access-Control-Allow-Origin の作用原理 - 個人記事 - SegmentFault 思否
処理方法#
-
拡張機能を使用して、ブラウザの同一生成元ポリシーのチェックを無効にします。拡張機能は、各リクエストのレスポンスに
Access-Control-Allow-Origin:*
のヘッダーを追加します。しかし、多くの場合、あまり効果的ではありません。 -
プロキシを介して、クライアントとサーバーの間の仲介者として機能します。このプロキシサービスは、フロントエンドの Web アプリがリクエストを送信し、サーバーからの返データを受け取って再びフロントエンドの Web アプリに送信するのを助けます。プロキシサービスは、元のレスポンスに
Access-Control-Allow-Origin: *
のヘッダーを追加します。例えば、Vue や React などのフレームワークを使用して API プロキシを設定します。この記事では、Vue を使用してプロキシを構築し、ローカルデータをプロキシポートを介して送信し、サーバーの同一生成元チェックポリシーを回避します。Vue の設定ファイル(vue.config.js)は次の通りです:module.exports = { devServer: { port: 12234, open: true, proxy: { '/api1': { // ローカルページアドレス/api1からのリクエストをインターセプト target: 'http://......', // 実際のバックエンドアドレス changeOrigin: true, // ここでtrueはクロスドメインを実現することを示します secure: false, // httpsインターフェースの場合、このパラメータを設定する必要があります pathRewrite: { '^/api1': '/' // /api1を/に書き換えます;サーバーが最終的に受け取るのは、ローカル12234ポートから送信されたデータです } }, '/api2': { // ローカルページアドレス/api2からのリクエストをインターセプト target: 'http://.....', // 別のバックエンドアドレス changeOrigin: true, // ここでtrueはクロスドメインを実現することを示します secure: false, // httpsインターフェースの場合、このパラメータを設定する必要があります pathRewrite: { '^/api2': '/' } } } } };
注意が必要なのは、Vue の設定ファイルはプロジェクトフォルダ内に配置し、main.js と同じ階層にする必要があります。
-
自分のプロキシを構築します。同一生成元ポリシーはブラウザとサーバー間にのみ適用され、サービス間の通信を制限しません。
uniapp+uView による複数のドメインまたはポートのリクエストの実現#
問題の説明#
プロジェクトコードでは、元々Http リクエスト | uView 2.0 - nvue に完全互換の uni-app エコシステムフレームワーク - uni-app UI フレームワーク (uviewui.com)を参考にして uView の http インターフェースを使用して、アクセスするパラメータやバックエンドアドレスなどのグローバル設定を行い、プラグインとしてmain.js
にインポートしていました。しかし、複数のドメインや異なるポートのドメインにアクセスする必要がある場合、このようなグローバル設定を使用することができません。
解決方法#
uView の http メソッドをラップして、異なるアクセスドメインまたはインターフェースを設定します。
-
設定ファイルにアクセスする必要のあるドメインまたはポートを記入します。
baseUrl_a: 'http://...', baseUrl_b: 'http://...',
-
uView http のグローバルパラメータを設定する際に、アクセスする URL を設定しません。
uni.$u.http.setConfig((config) => { // ドメイン設定 // config.baseURL = projectConfig.baseUrl; ... ...
-
新しい js ドキュメントを作成し、異なるドメインに基づいて異なるアクセス方法を設定します。
// requestConfig.js const http = uni.$u.http; // 第一のインターフェースの2つの方法 export function http_a_get(path,params = ''){ return http.get(projectConfig.baseUrl_a + path, {params}); } // 第二のインターフェースの2つの方法 export function http_b_get(path,params = ''){ return http.get(projectConfig.baseUrl_b + path, {params}); }
-
main.js
でインポートし、プロトタイプに追加します。import {http_a_get,http_b_get} from '..../reuquestConfig.js'; Vue.prototype.$http_a_get = http_a_get; Vue.prototype.$http_b_get = http_b_get;
-
実際の使用では、ラップされた関数を直接呼び出します。新しいポートや対応するメソッドを追加する必要がある場合は、設定ファイルにポートを追加し、必要なメソッドをラップし、最後に main.js にプロトタイプに追加します。既存のポートの変更は、URL の設定ファイルで変更するだけで済みます。
export function getId(params) { return http_a_get('/ポート後のパス', params); }