クロスドメイン問題#
問題の説明#
ブラウザはクロスサイトリクエストフォージェリ攻撃を防ぐために、同一オリジンポリシーを設定しています。フロントエンドのローカル開発の URL は大抵「http+localhost + ポート」であり、これによりクロスドメイン、クッキーの植え付け、外部サービスの呼び出しに実際のドメイン名が必要になる問題が発生します。
同一オリジンポリシーとは、2 つのオリジンが相互に通信できるのは、プロトコル、ドメイン名、ポートがすべて一致する場合のみを指します。これはリクエストの安全性を確保し、悪意のある攻撃を減らすためです。
クッキーの植え付け問題 -- フロントエンドとバックエンドの認証がクッキーに関わる場合、localhost のようなドメイン名がクッキーの植え付けに影響を与えます。ブラウザがクッキーを正しく植え付けるかどうかは、ドメインの影響を受けます。
外部サービスの呼び出しには実際のドメイン名が必要です。プロジェクトが外部サービスを呼び出す際、しばしば完全な実際のドメイン名が必要です。例えば、WeChat ログインなどです。この時、ローカル開発では完全な実際のドメイン名がないため、ローカルでの調整ができません。
同一オリジンを検証するために、ブラウザはすべてのリクエストに特別なリクエストを付加して、ドメイン情報を受信するサーバーに送信します。サーバーから返されるレスポンスには、Access-Control-Allow-Origin
というキーを含むヘッダーが付加され、どのようなオリジンがサーバーのリソースにアクセスできるかを示します。通常、2 つのモードに分かれます。値が * の場合、サーバーは任意のオリジンが自分のリソースにアクセスすることを許可します。もう一つのモードは、指定されたオリジンの権限でアクセスすることです。
フロントエンド - 【訳】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); }