Vee互換ie 9の包括的なソリューション

8412 ワード

前言
背景状況
  • vue - 2.5.11
  • vue-cli使用テンプレートwebpack-simple
  • httpリクエスト:axios
  • Vueの公式ieブラウザバージョンの互換性の説明はie 9+、すなわちie 9以上のバージョンである.Vueのコアフレームワークvuejs自体、およびエコの公式コアプラグイン(VueRouter、Vuexなど)はie 9上で正常に使用できることが試験された.
    Vueの著者である尤雨渓は、Vueの学習提案において、プロジェクトのより良い生態化/エンジニアリング化のために、できるだけ新しいECMAScript規範を学習し、使用することに言及している.現在、ES 6/ES 2015は可用性と安定度の高い規範であり、ドキュメントがそろっており、国内にはチェン一峰の「ECMAScript 6入門」が大量のドキュメント翻訳を行い、開発環境が完備していると言える.しかし、バージョンの古いブラウザはes 6仕様をサポートしていません.特にieブラウザは、最も高いie 11バージョンであっても、es 6仕様についてはサポートされていません.このように、ES 6の特性をサポートしていないすべてのブラウザに対して互換性処理を行う必要があります.
    本稿では,Vueエコ開発を用いたWebサイトについて,ie 9バージョンをベースとした互換性目標を達成し,全機能正常使用の包括的な互換性ソリューションを実現する.
    ES 6互換
    ie 9の環境では、es 6の一部の新しいオブジェクト、式はサポートされておらず、ソリューションはbabel-polyfillコンポーネントを使用して、es 6のコードを低バージョンブラウザで識別できるes 5コードに翻訳することができる.
    npm i babel-polyfill --save-dev
    

    インストールが完了すると、プロジェクトのメインエントリファイルmain.jsの最初の行で直接参照できます.
    import 'babel-polyfill';
    

    プロジェクトがvue-cliを使用して生成されたコードでは、ルートディレクトリには.babelrcファイルがあり、これはプロジェクトがbabelを使用するプロファイルです.デフォルトで生成されたテンプレートコンテンツには、polyfill(互換性)が必要な設定を指定する"useBuiltIns": "entry"の設定内容が追加されます.
    useBuiltInsには3つの設定オプションがあります
  • false-何もしない
  • entry-ブラウザバージョンのサポートに基づいてpolyfill需要を分割して導入し、ブラウザでサポートされていないpolyfill
  • のみを導入する.
  • usage-検出コードにおけるES6/7/8等の使用状況は、コードに用いるpolyfill
  • のみをロード.
    ここではentryに設定することをお勧めします.完全な.babelrcの内容は以下の通りです.
    {
      "presets": [
        [
          "env",
          {
            "modules": false,
            "useBuiltIns": "entry"
          }
        ],
        "stage-3"
      ]
    }
    
    

    これらのコードを追加すると、エンジニアリングのほとんどのコンテンツがie 9バージョンに互換性があります.
    Numberオブジェクトbabel-polyfillを用いてコード翻訳を行った後も、NumberオブジェクトのparseIntおよびparseFloatメソッドのようなes 6の新しい特性が解決されていないことが分かった.
    Es 6は、グローバルメソッドparseInt()およびparseFloat()を、Numberオブジェクト上に移植し、動作は完全に一定に保たれる.このような目的は,グローバルメソッドを徐々に減らし,言語を徐々にモジュール化することである.
    この問題を解決するには、パッケージを導入して解決する必要はありません.同様に、プロジェクトのメインエントリファイルmain.jsに以下のコードが追加されます(コードはできるだけ前で、babel-polyfillを参照した後が望ましいです).
    if (Number.parseInt === undefined) Number.parseInt = window.parseInt;
    if (Number.parseFloat === undefined) Number.parseFloat = window.parseFloat;
    

    requestAnimationFrameメソッドwindow.requestAnimationFrameは、ブラウザがタイミングループ動作のために使用するインタフェースであり、setTimeoutと同様に、主な用途はフレームごとにウェブページを再描画することである.requestAnimationFrameの利点は、ディスプレイのリフレッシュメカニズムを十分に利用し、システムリソースを比較的節約することにある.ディスプレイには固定リフレッシュ周波数(60 Hzまたは75 Hz)があり、つまり、毎秒最大60回または75回しか再描画できないということであり、requestAnimationFrameの基本思想はこのリフレッシュ周波数と同期して、このリフレッシュ周波数を利用してページ再描画を行うことである.また、このAPIを使用すると、ページがブラウザの現在のラベルにないと、自動的にリフレッシュが停止します.これにより、CPU、GPU、電力が節約されます.
    ただし、requestAnimationFrameはプライマリスレッド上で完了していることに注意してください.これは、メインスレッドが非常に忙しい場合、requestAnimationFrameのアニメーション効果が大幅に低下することを意味します.window.requestAnimationFrame()メソッドは、ブラウザにアニメーションを実行するように伝え、次に再描画する前に指定した関数を呼び出してアニメーションを更新するようにブラウザに要求します.このメソッドは、ブラウザが再描画する前に呼び出されるパラメータとしてコールバック関数を使用します.
    一部のサードパーティコンポーネントは、一部のファイルアップロード、ピクチャ処理クラスのコンポーネントなど、この方法を使用しています.では、このタイプのコンポーネントがie 9で使用されると、
    SCRIPT5007: Expected object.
    
    window.requestAnimationFrame()の最低互換ieバージョンは10で、ie 9で互換を作るにはrequestAnimationFrame polyfillを作成する必要があります
    (function() {
        var lastTime = 0;
        var vendors = ['ms', 'moz', 'webkit', 'o'];
        for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
            window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
            window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] 
                                       || window[vendors[x]+'CancelRequestAnimationFrame'];
        }
     
        if (!window.requestAnimationFrame)
            window.requestAnimationFrame = function(callback, element) {
                var currTime = new Date().getTime();
                var timeToCall = Math.max(0, 16 - (currTime - lastTime));
                var id = window.setTimeout(function() { callback(currTime + timeToCall); }, 
                  timeToCall);
                lastTime = currTime + timeToCall;
                return id;
            };
     
        if (!window.cancelAnimationFrame)
            window.cancelAnimationFrame = function(id) {
                clearTimeout(id);
            };
    }());
    

    Gist:requestAnimationFrame polyfill
    このコードは、できるだけサイトの入り口で実行されます.
    httpネットワークリクエスト(ドメイン間)
    ほとんどのWebプロジェクトでは(JavaWebを例に)、ウェブサイトのページとサービス(少なくともcontroller層)が同じプロジェクトで開発され、導入されています.大フロントエンドの新しいモデルでは、できるだけウェブサイトのフロントエンドとバックエンドを完全に分離することをお勧めします.前後エンドの分離のメリットと意味はここでは説明しません.
    前後が分離されている以上、デプロイメントも必ず独立してデプロイメントされ、異なるアクセスパスによってドメイン間アクセスの問題が発生します(同じサイト、異なるポート番号もドメイン間)
    背景を設定します.
  • サービス側はCROSドメイン間サポート
  • を完全にオープンした.
  • httpコンポーネントaxios
  • を使用
  • axios設定withCredentialsは、trueがドメイン間アクセスを開始するときにcookieデータを携帯する
  • である.
    高バージョンブラウザ(ie 10+またはchrome,ff)は、バックグラウンドの機能を完了するだけで、ドメイン間データ要求機能をサポートします.
    axiosがデータ要求を行う場合、デフォルトではXMLHttpRequestオブジェクトが使用され、現在の要求がドメイン間アクセスであることが検出されると、axiosはブラウザがXDomainRequestオブジェクトをサポートしているかどうかをテストし、サポートされている場合は優先的に使用します.
    ie 8/ie 9のXMLHttpRequestオブジェクトは、ie 10後にドメイン間アクセスをオリジナルでサポートするドメイン間アクセスをサポートしない.マイクロソフトのソリューションは、ie 8/ie 9にXDomainRequest(XDR)オブジェクトを提供してドメイン間問題を解決することです.このオブジェクトを使用すると、ドメイン間アクセスに成功し、データを返すことができますが、依然として機能が不完全な半製品であり、使用には多くの制限があります.
  • XDRは、GETとPOSTの両方の要求方式
  • のみをサポートする.
  • XDRはカスタム要求ヘッダをサポートするものではなく、サービス側がheaderのカスタムパラメータを使用して認証を行う場合、
  • は使用できない.
  • 要求ヘッダのContent-Typeは、text/plainに設定された
  • のみを許可する.
  • XDRはプロトコル間の要求を許さず、ウェブページがHTTPプロトコルの下にある場合、HTTPプロトコルの下のインタフェースしか要求できず、HTTPSインタフェース
  • にアクセスできない.
  • XDRはHTTP/HTTPSの要求
  • のみを受け入れる.
  • が要求を開始するときは、authenticationまたはcookies
  • を携帯しない.
    マイクロソフトはソリューションを提供していますが、システム内のさまざまなシーンのデータ要求のニーズに耐えられないほど、axiosはie 9のドメイン間データ要求に対して何もできません.
    完璧なソリューション:エージェント(proxy)
    axiosはie 9のドメイン間では何もできませんが、フロントエンドのプロジェクトパッケージのソリューションwebpackは、優雅で徹底的に問題を解決する方法を提供しています.エージェント
    devServer.proxy
    WebpackのdevServer.proxyの機能はhttp-proxy-middlewareプロジェクトによって実現される
    実現原理は,ターゲット位置のリクエストエージェントをフロントエンドサービスローカルのリクエストとし,エージェントがローカルのリクエストとなる以上ドメイン間の問題はなくaxiosはXMLHttpRequestオブジェクトに戻ってデータリクエストを行い,すべてが正常に回復し,header,cookies,content-type,authenticationなどのコンテンツがサービス側に正しく伝達される.
    プロジェクト中webpack.config.jsの構成
    devServer: {
        historyApiFallback: true,
        noInfo: true,
        overlay: true,
        proxy: {
            '/api': {
                target: 'http://localhost:8081/myserver',
                pathRewrite: {
                    '^/api': ''
                }
            }
        }
    }
    

    構成では、http://localhost:8081/myserverサービスのロケーションエージェントをローカルフロントエンドサービスのhttp://localhost:8080/apiとして指定している.例えば、ユーザ情報を読み取る必要がある元の要求はhttp://localhost:8081/myserver/user/zhangsanであり、エージェント後、http://localhost:8080/api/user/zhangsanとなる.
    すなわち、/apiのプレフィックスはサービス側を表すので、axiosを使用する場合、各サービス側要求に/apiのプレフィックスを追加する必要がある.通常、プロジェクト開発では、デフォルトパラメータの統一設定、データ要求エントリの統一などの目的を達成するために、データ要求コンポーネントaxiosを二次カプセル化する必要があるが、この場合、二次カプセル化されたファイルで要求プレフィックスを統一的に調整するだけでよい.
    ただし,webpackのdevServer.proxyは開発モードのみで利用可能であり,生産モードでは使用できない.開発モードでは、デバッグサービスはwebpack.config.jsの構成内容を読み出してリアルタイムエージェントを行うことができ、プロジェクトは本番環境に配備される前に、エンジニアリングをコンパイルして静的jsファイルに変換する必要があり、デバッグサービスのサポートがなければ要求エージェントを行うことはできない.
    nginx構成devServer.proxyの機能は開発モデルでしか機能しないが、生産モデルでは当然解決策がある.通常、Vueのプロジェクトは最終的なjsファイルにコンパイルされた後、静的サーバのみが必要であり、そのうちnginxを最適選択案とし、軽量、高性能、高同時、逆エージェントサービスなどが利点であり、ここで必要なデータ要求エージェントの機能はnginxの逆エージェント機能に使用されるconf/nginx.confファイル構成追加
    location /api/ {
        proxy_pass http://localhost:8081/myserver/;
    }
    

    この構成は、http://localhost:8081/myserver/のターゲット・サービス・エンド・ロケーション・エージェントをローカル・サービスとする/apiパスであり、これにより、本番環境におけるデータ要求の問題も解決される.
    個人オリジナルコンテンツ、転載は出典を説明してください
    完全な内容:https://github.com/TerryZ