ホームページ  >  記事  >  ウェブフロントエンド  >  これらのブラウザ インタビューの質問を見てください。何問正しく答えることができますか?

これらのブラウザ インタビューの質問を見てください。何問正しく答えることができますか?

青灯夜游
青灯夜游転載
2022-03-23 10:39:593656ブラウズ

この記事では、ブラウザに関する面接の質問をいくつか紹介します。いくつ答えられるかわかりますか?正解を分析して、何問正解できるかを確認してください。

これらのブラウザ インタビューの質問を見てください。何問正しく答えることができますか?

#1. 一般的なブラウザ カーネルとは何ですか?

ブラウザのコアは 2 つの部分に分けることができます:

レンダリング エンジン JS エンジン (注: 私たちがよく言及するブラウザ カーネルはレンダリング エンジンを指します )

JS エンジンがますます独立するようになるにつれて、カーネルはレンダリング エンジンのみを指します。これは主にリクエストに使用されます。ネットワーク ページ リソースは解析およびタイプセットされ、ユーザーに表示されます

##ブラウザ/ランタイムカーネル (レンダリング エンジン)JavaScript エンジンChromeBlink (28~) Webkit (Chrome 27) V8FireFoxGeckoSpiderMonkeySafariWebkit JavaScriptCoreEdgeEdgeHTMLChakra (JavaScript 用)IETrident Chakra (JScript 用)OperaPresto->blinkLinear A (4.0-6.1) /リニアB (7.0-9.2) / フサルク (9.5-10.2) / カラカン (10.5-) Node.js-V8 ##############################

2. ブラウザの主なコンポーネントは何ですか?

  • ユーザー インターフェイス: アドレス バー、進む/戻る/更新/ブックマーク、その他のボタンを含む

  • ブラウザ エンジン: ユーザー インターフェイスとレンダリング内エンジン

  • レンダリング エンジン: 要求されたコンテンツの描画に使用されます。

  • ネットワーク: http リクエストなどのネットワーク呼び出しを完了するために使用されます。プラットフォームに依存しないインターフェイスを備えており、さまざまなプラットフォームで動作できます

  • #JavaScript インタープリター: JavaScript コードの解析と実行に使用されます

  • ユーザー インターフェイス バックエンド: コンボ ボックスやウィンドウなどの基本的なウィジェットを描画するために使用されます。最下層はオペレーティング システムのユーザー インターフェイスを使用します。

  • データ ストレージ: 永続化レイヤーとブラウザーに属します。 HTML5 は、さまざまなデータに対して、軽量で完全なクライアント側のストレージ テクノロジである Web データベース テクノロジを定義します。

    注 : ほとんどのブラウザとは異なり、Google Chrome の各タブはレンダリング エンジン インスタンスに対応します。各タブは独立したプロセスです

3. URL の入力からページのレンダリングまでの処理について説明します。

この質問は面接で最も一般的な質問と言え、限りなく難しい場合があります。通常、面接官はあなたのフロントエンドの知識の深さをテストするためにこの質問をします。

これらのブラウザ インタビューの質問を見てください。何問正しく答えることができますか?

1. ブラウザは URL を受け入れ、ネットワーク リクエスト スレッドを開きます (ブラウザのメカニズム、スレッド、プロセスなどが含まれます)

2. ネットワーク スレッドを開いて、完全な http リクエスト (関連: DNS クエリ、TCP/IP リクエスト、5 層ネットワーク プロトコルなど)

3. サーバーから対応するバックエンドへのリクエストを受信します (関連: ロード バランシング、セキュリティ インターセプト、バックエンドの内部処理など)

4. バックエンドとフロントエンド間の HTTP 対話 (http ヘッダー、応答コード、メッセージ構造、Cookie などを含む)

5. キャッシュの問題 (関係: http 強力なキャッシュ キャッシュ、キャッシュ ヘッダー、etag、期限切れ、キャッシュ制御などのネゴシエート)

6. ブラウザが http パケットを受信した後の解析プロセス (HTML 字句解析、DOM への解析を含む)

7. CSS ビジュアル モデル (CSS のビジュアル モデル (含む)) : 要素レンダリング ルール (ブロック、コントロール ボックス、BFC、IFC などが含まれます)

8. JS エンジン解析プロセス (以下が含まれます: JS 解析フェーズ、前処理フェーズ、実行コンテキストを生成する実行フェーズ、 VO (グローバル オブジェクト)、スコープ チェーン、リサイクル機構など)

単純な URL を入力してからページが表示されるまでに非常に多くの処理が発生することがわかります。 (心配しないでください、この章ではこれを行いません。最初にこの質問に答える方法を教えましょう。このセクションについては別の記事で説明します)

ブラウザは、DNS サーバーを通じてドメイン名の IP アドレスを取得し、この IP アドレスから要求します。HTML テキスト

##ブラウザのレンダリング プロセスは、HTML テキストを解析し、DOM ツリーを構築します

HTML の解析中に、インライン スタイルまたはスタイル ファイルが見つかった場合は、スタイル ルールがダウンロードされて構築されます。JavaScript スクリプトが見つかった場合は、実行スクリプトがダウンロードされます

DOM ツリーと CSSOM が構築された後, レンダリング プロセスは、2 つをレンダー ツリー (レンダー ツリー) にマージします
  • レンダリング プロセスは、レンダリング ツリーのレイアウトを開始します。レイアウト ツリーの生成
  • レンダリング ツリーは、レイアウト ツリーを描画し、描画レコード
  • 4. ブラウザはどのようにコードを解析しますか?
HTML の解析

これらのブラウザ インタビューの質問を見てください。何問正しく答えることができますか?

HTML は行ごとに解析され、ブラウザのレンダリング エンジンが HTML ドキュメントを解析して DOM ノードに変換します。

HTML を多数のトークンに解析するトークンをオブジェクトに解析する

オブジェクトを DOM ツリーに結合する

  • Parse CSS
ブラウザは CSS セレクターを右から左に解析します

DOM ツリーと CSSOM ツリーがマージされていることがわかります。レンダー ツリーは実際に CSSOM を DOM ツリーにアタッチするため、セレクターによって提供される情報に基づいて DOM ツリーを走査する必要があります。 #例を見てみましょう:

<style>
.nav .title span {color:blue}
</style>

<div class=&#39;nav&#39;>
  <div class=&#39;title&#39;>
    <span>南玖</span>
  </div>
  <div class="sub_title">前端</header>
</div>

右から左へのマッチング:

##まず、各スパンについて、右端のノード スパンをすべて見つけます。 h3 からノード div.title

を探し、次にノード div.nav

  • 最後にルート要素 html を見つけます。その後、このブランチのトラバースを終了します。

  • JS の解析
  • ブラウザには、JS を解析するために特別に使用される JS パーサー ツールがあります。コード。
ブラウザは js コードに遭遇すると、すぐに「js パーサー」を呼び出して動作させます。

パーサーは、js 内のすべての変数、関数、パラメーターなどを検索し、変数の値を未定義に割り当てます。

関数を関数ブロックに取り出してウェアハウスに保管します。これが完了すると、コードは 1 行ずつ (上から下、左から右へ) 解析され、ウェアハウスとの照合が開始されます。

5.DOMContentLoadedとloadの違いは何ですか?

  • DOMContentLoaded: スタイル シート、画像、その他のリソースを除き、DOM 解析が完了した後にのみトリガーされます。
  • Load: ページ上のすべての DOM、スタイル シート、スクリプト、画像、その他のリソースが読み込まれるとトリガーされます。

6. ブラウザの再描画とドメインの再配置の違いは何ですか?

  • 再配置: レンダリング ツリーの一部または全体を再解析し、ノード サイズを再計算する必要があります。これは、レイアウトの再生成と要素の再配置を意味します
  • 再描画: ノードの幾何学的プロパティの変更や、要素の背景要素などのスタイルの変更により、一部の要素の外観が変更されます

# #再描画は必ずしもリフローを引き起こすわけではありませんが、リフローは再描画を引き起こす必要があります

再描画とリフローをトリガーするにはどうすればよいですか? #レンダー ツリーの構築に使用される情報を変更すると、リフローまたは再描画が発生します:

DOM ノードの追加、削除、更新
  • 表示による DOM ノードの非表示: なし - リフローと再描画のトリガー
  • 表示による DOM ノードの非表示: 非表示 - 幾何学的変化がないため、再描画のみをトリガーします
  • 移動または追加を指定しますページ内の DOM ノードへのアニメーション
  • スタイル シートを追加し、スタイル属性を調整します
  • ウィンドウ サイズの調整、フォント サイズの変更、スクロールなどのユーザーの動作。

再描画やリフローを回避するにはどうすればよいですか?

    スタイルを一元的に変更する: たとえば、クラスを使用してスタイルを一括変更します
  • Use
  • document .createDocumentFragment ()

    : createDocumentFragment を使用して DOM ツリーの外にノードを作成し、このノードでバッチ操作を実行し、最後にそれを DOM ツリーに挿入することができるため、再配置は 1 つだけトリガーされます

  • コンポジション レイヤーへの昇格
  • 要素をコンポジション レイヤーにプロモートすると、次の利点があります:

      コンポジション レイヤーのビットマップは ## に渡されます。 #GPU
    • 合成、

      CPU 処理より高速

    • repaint
    • が必要な場合、

      repaint 自体のみが必要です必須ですが、他のレイヤーには影響しません

    • transform
    • および

      opacity 効果の場合、layout および paint は影響しません#コンポジション レイヤーを強化する最良の方法は、CSS will-change プロパティ

      # を使用することです。 #7. JS はなぜシングルスレッドなのでしょうか?
    これは主に JS の目的に関係しますが、JS はブラウザのスクリプト言語として、当初は主にユーザーとブラウザ間の対話を実現し、DOM を操作するために使用されていました。これにより、シングルスレッドのみが可能であることが決まります。そうでない場合は、多くの複雑な同期問題が発生します。

例:

JS がマルチスレッドで、あるスレッドが DOM 要素を変更したいと考えており、別のスレッドが DOM 要素を削除したいと考えている場合、ブラウザは何をすべきかわかりません。誰の話を聞きますか?したがって、複雑さを避けるために、JavaScript は誕生以来シングルスレッドになるように設計されてきました。

マルチコア CPU の計算能力を活用するために、HTML5 は Web Worker 標準を提案しています。これにより、JavaScript スクリプトは複数のスレッドを作成できますが、子スレッドはメインスレッドによって完全に制御されます。スレッドを実行する必要があり、DOM を操作してはなりません。したがって、この新しい標準は JavaScript

8 のシングルスレッドの性質を変更しません。CSS の読み込みは DOM をブロックしますか?

#最初に結論を述べます

##CSSDOM

解析をブロックしませんただし、
DOM
  • CSS のレンダリングはブロックされます。JS の実行はブロックされますが、JS
  • ダウンロードはブロックされません。ファイル
  • #CSSOM の役割

最初のファイルは JavaScript 操作用に提供されます。スタイル シートの機能2 つ目は、レイアウト ツリーの合成のための基本的なスタイル情報を提供することです。

  • この CSSOM は、 DOM

    document.styleSheets
  • 前述のブラウザのレンダリング プロセスからわかります:
  • DOM と CSSOM は通常、並行してビルドされるため、

    CSS の読み込みによって DOM 解析がブロックされることはありません

    レンダー ツリーは DOM ツリーと CSSOM ツリーに依存しているため、両方のレンダリングが完了するまで待機する必要があります。読み込みが完了するまで開始できないため、
  • CSS 読み込みにより DOM のレンダリングがブロックされます

  • JavaScript は DOM と CSS を操作できるため、これらの属性を変更すると同時に要素を取得する インターフェイスがレンダリングされる (つまり、JavaScript スレッドと UI スレッドが同時に実行される) 場合、レンダリング スレッドの前後で取得される要素が矛盾する可能性があります。したがって、予期しないレンダリング結果を防ぐために、ブラウザは
  • GUI レンダリング スレッドと JavaScript スレッドを相互排他的になるように設定します。

  • JS CSS のダウンロードを待機している必要があります。これはなぜですか? (CSS は DOM の実行をブロックします)

    JS スクリプトの内容が要素のスタイルを取得することである場合、CSS に依存する必要があります。ブラウザは JS が内部的に何を行おうとしているのかを感知できないため、スタイルの取得を避けるために、以前のすべてのスタイルがダウンロードされるまで待ってから JS を実行する必要があります。ただし、JS ファイルと CSS ファイルは並行してダウンロードされ、後続の JS ファイルが実行される前に CSS ファイルがロードされて実行されるため、CSS は後続の JS

    の実行をブロックします。 白い画面を回避し、CSS の読み込み速度を向上させます

    • CDN を使用します (CDN はキャッシュされたコンテンツを持つ最も近いノードを選択し、ネットワークに基づいてリソースを提供します)
    • CSS を圧縮する
    • キャッシュを適切に使用する
    • http リクエストの数を減らし、CSS ファイルをマージする

    9 .JS はページをブロックしますか?

    最初に結論を述べます

    JS は DOM の解析をブロックするため、ページの読み込みもブロックします

    これが、JS ファイルを一番下に置くべきだとよく言われる理由です。

    JavaScript は DOM を操作できるため、これらの属性を変更すると、要素のレンダリングとインターフェイスのレンダリングを同時に実行すると (つまり、JavaScript スレッドと UI スレッドが同時に実行されます)、レンダリング スレッドの前後で取得された要素データが不一致になる可能性があります。

    したがって、予期しないレンダリング結果を防ぐために、ブラウザは **「GUI レンダリング スレッドと JavaScript エンジンは相互に排他的である」** 関係を設定します。

    JavaScript エンジンの実行中、GUI スレッドは一時停止され、GUI の更新はキューに保存され、エンジン スレッドがアイドル状態になるとすぐに実行されます。

    ブラウザが JavaScript プログラムを実行している場合、GUI レンダリング スレッドはキューに保存され、JS プログラムが完了するまで実行されません。

    したがって、JS の実行時間が長すぎると、ページのレンダリングに一貫性がなくなり、ページのレンダリングと読み込みがブロックされたように感じられます。

    10.遅延と非同期の違いは何ですか?

    • どちらも外部 JS ファイルを非同期で読み込み、DOM 解析をブロックしません。
    • Async は、外部 JS 読み込みが完了した後、ブラウザがアイドル状態で、Load イベントが実行される前に実行されます。この属性は、インライン スクリプト (つまり、「src」属性のないスクリプト) には影響しません。
    • defer は、JS がロードされた後、ドキュメント全体が解析された後、DOMContentLoaded イベントがトリガーされる前に実行されます。 script) が欠落している場合、この場合には効果がないため、属性は使用しないでください
    • 11. ブラウザーのガベージ コレクション メカニズム

    ガベージ コレクションは自動メモリです管理メカニズム。コンピュータ上の動的メモリは、不要になったら解放する必要があります。

    自動とは、ブラウザがメモリのゴミを自動的にリサイクルできることを意味しますが、メモリ管理を気にする必要がないことを意味するわけではありません。正しく動作しない場合、メモリ オーバーフローが発生します。 JavaScript では依然として発生し、システムのダウンを引き起こします。

    文字列、配列、オブジェクトなどには固定サイズがないため、サイズがわかっている場合は動的に割り当てる必要があります。 JavaScript プログラムが文字列、配列、またはオブジェクトを作成するたびに、インタープリターはそのエンティティを格納するためにメモリを割り当てる必要があります。

    JavaScript インタプリタは、プログラムがオブジェクトを使用しなくなったことを検出できます。オブジェクトが役に立たないと判断すると、そのオブジェクトが不要であることがわかり、オブジェクトが占有しているメモリを解放できます。

    ブラウザが通常使用するガベージ コレクションには、

    マークのクリア

    参照カウントの 2 つの方法があります。

    マークのクリア

    これは、JavaScript で最も一般的に使用されるガベージ コレクション メソッドです。 2012 2000 年以降、すべての最新のブラウザーはマーク アンド スイープ ガベージ コレクション方式を使用しています。ただし、IE の下位バージョンでは依然として参照カウント方式が使用されています。

    それでは、マーク除去とは何でしょうか?

    JavaScript にはグローバル オブジェクトがあります。定期的にガベージ コレクターはこのグローバル オブジェクトから開始し、このグローバル オブジェクトから参照されるすべてのオブジェクトを検索し、次にこれらのオブジェクトによって参照されるオブジェクトを検索します。オブジェクト...これらのアクティブなオブジェクトをマークします。これがマーキング フェーズです。クリア段階では、マークされていないオブジェクトをクリアします。

    マークのクリアに関する問題の 1 つは、クリア後のメモリ空間が不連続になる、つまりメモリの断片化が発生することです。後で比較的大きな連続メモリ空間が必要になった場合、要件を満たせなくなります。
    マーキングと並べ替え

    メソッドは、この問題を効果的に解決できます。

    マーキングのプロセスでは、3 色マーキングの概念が導入されます。3 色は次のとおりです:

    白: マークされていないオブジェクト、つまり、到達できないオブジェクト (スキャンされたオブジェクトではありません) )、リサイクル可能

    灰色: オブジェクトはマークされています (到達可能なオブジェクト) が、オブジェクトはまだスキャンされていないため、リサイクルできません

      黒: スキャン済み (到達可能)オブジェクト)、リサイクル不可
    • タグの並べ替え:
    • マーキングフェーズは、マークアンドクリアメソッドと何ら変わりませんが、マーキングが完了した後、マークアンドクリアメソッドは残っているオブジェクトをメモリの片側に移動し、最後に境界をクリーンアップします。メモリ。

      #参照カウント

      参照カウントの意味は、各値が参照された回数を追跡することです。変数 A に値が割り当てられると、この値への参照の数は 1 になります。変数 A が再割り当てされると、前の値への参照の数は 1 減ります。参照の数が 0 になると、この値にアクセスする方法がなくなったことを意味するため、この値によって占有されていたメモリをクリアできます。

      #ほとんどのブラウザはこのリサイクル方法を放棄しました

      メモリ リーク

      メモリ リークを回避するには、データが使用されなくなったら、その値を
      null

      に設定して参照を解放するのが最善です。このメソッドは Contact Reference # と呼ばれます。

      ##どのような状況でメモリ リークが発生する可能性がありますか?それを避けるにはどうすればよいでしょうか?

      Vue を例にとると、通常は次のような状況があります。

      window/body
        などのリッスン イベントはバインドされていません
      • EventBus
      • に関連付けられたイベントは、
      • Vuex
      • $store から関連付けられておらず、その後に がありませんwatch は削除されました。unwatchサードパーティのライブラリを使用して作成され、正しい破棄関数が呼び出されません
      • 解決策: # で時間内に破棄します。 ##beforeDestroy

      DOM/BOM オブジェクト内のバインドされたイベント

      addEventListener
        および
      • removeEventListenerオブザーバー モード $on$off
      • 処理。
      • コンポーネントでタイマーが使用されている場合は、それを破棄する必要があります。 サードパーティのライブラリの初期化が mounted/created
      • フックで使用されている場合、それはそれに応じて破棄されます。
      • 弱い参照
      • weakMapweakSet
      • を使用します。
      • ブラウザ内のさまざまなタイプの変数のメモリはいつ解放されますか?

      #参照タイプ

      参照がなくなると、V8 によって自動的にリサイクルされます。
        • 基本型
        クロージャ内にある場合、クロージャへの参照がなくなるまで、V8 によってリサイクルされません。
      • 非閉鎖の場合は、V8 の新世代が切り替わる際のリサイクルを待ちます。

        • 12. ブラウザのキャッシュ メカニズムについて話しますか?
      ブラウザ キャッシュについて理解する

      ブラウザが Web サイトをリクエストすると、さまざまなリソースが読み込まれます。頻繁に変更されない一部のリソースについては、ブラウザはそれらをローカル メモリに保存し、次回アクセスするときにこれらのリソースを直接ロードして、アクセス速度を向上させます。

      リソースが要求されたサーバーであるかキャッシュ読み取りであるかを確認するにはどうすればよいですか?

      上の図を見てください。一部のリソースのサイズ値はサイズであり、一部は

      ディスク キャッシュ

      からのものであり、一部は これらのブラウザ インタビューの質問を見てください。何問正しく答えることができますか?メモリ キャッシュ

      からのもので、表示されているサイズは要求されたサーバー リソースであり、後の 2 つは読み取りキャッシュです。

      ディスク キャッシュ: はリソースをディスクに保存します。次のアクセスを待つときに再ダウンロードする必要はなく、ディスクから直接読み取ることができます。その直接操作オブジェクトは

      CurlCacheManager
        です。 (メモリキャッシュに比べて効率は劣りますが、記憶容量が大きく、記憶時間が長い)
      • メモリキャッシュ: リソースをメモリにキャッシュすることを意味します。次のアクセスを待つときに再度ダウンロードする必要があるため、メモリから読み取ります。 (効率の点では最も速く、生存時間の点では最も短いです。)
      • -
メモリ キャッシュディスク キャッシュ同じ点一部の派生リソース ファイルのみ保存可能一部のみ保存可能派生クラスのリソース ファイル違いプロセスの終了時にデータはクリアされますプロセスの終了時にデータはクリアされませんストレージ リソース通常、スクリプト、フォント、画像はメモリに保存されます通常、CSS などのスクリプト以外はメモリに保存されます。など

ブラウザ キャッシュの分類

  • 強力なキャッシュ
  • ネゴシエーション キャッシュ

ブラウザがサーバーにリソースを要求すると、まず強力なキャッシュにヒットするかどうかを判断し、失敗した場合は、ネゴシエートされたキャッシュにヒットするかどうかを判断します

強力なキャッシュ

ブラウザがリソースをロードすると、まずローカル キャッシュ リソースの header に基づいて強力なキャッシュがヒットしたかどうかが判断されます。ヒットした場合、キャッシュはサーバーにリクエストを送信せずに直接使用されます。 (ここでのヘッダーの情報は、expires および cache-control を指します)

  • #Expires

このフィールドは

http1.0 の仕様であり、その値は absolute time 文字列の GMT 形式の時刻文字です。有効期限:2066 年 10 月 18 日月曜日 23:59:59 GMT など。この時間は、このリソースの有効期限を表します。この時間より前に、キャッシュがヒットします。この方法には明らかな欠点があり、有効期限が絶対時間であるため、サーバーとクライアント間の時間のずれが大きい場合、キャッシュの混乱が発生します。そのため、このメソッドは HTTP 1.1 の後のバージョンではすぐに廃止されました。

  • Cache-Control

Cache-Control が

http1.1## の場合に表示されるヘッダー# 情報は主に、Cache-Control:max-age=3600## など、相対時間であるこのフィールドの max-age 値を使用して判断されます。 # 、これはリソースの有効期間が 3600 秒であることを意味します。このフィールドに加えて、cache-control には次の一般的に使用される設定値もあります。 no-cache

: キャッシュをネゴシエートし、確認するためにサーバーにリクエストを送信する必要があります。キャッシュを使用するかどうか。

no-store

: キャッシュの使用を無効にし、毎回データを再リクエストします。

public

: エンド ユーザーや CDN などの中間プロキシ サーバーを含むすべてのユーザーがキャッシュできます。

private

: エンド ユーザーのブラウザによってのみキャッシュでき、CDN などのリレー キャッシュ サーバーによってキャッシュすることは許可されません。

Cache-Control と Expires はサーバー構成で同時に有効にすることができます。同時に有効にすると、Cache-Control の優先順位が高くなります。

ネゴシエーション キャッシュ

強力なキャッシュが見つからない場合、ブラウザはサーバーにリクエストを送信し、サーバーはこれに続きます。 ヘッダー

の情報は、ネゴシエーション キャッシュがヒットしたかどうかを判断するために使用されます。ヒットした場合は、

304 が返され、リソースが更新されていないため、ローカル キャッシュを使用できることがブラウザに通知されます。 (ここでのヘッダー情報は、Last-Modify/If-Modify-Since および ETag/If-None-Match を指します)

    Last-Modify/If-Modify-since
  • ブラウザが初めてリソースをリクエストすると、サーバーから返されるヘッダーはLast-modify と合わせて、Last-modify はリソースの最終変更時刻を識別する時刻です。
ブラウザがリソースを再度リクエストすると、リクエスト ヘッダーには If-Modify-Since が含まれます。これは、キャッシュする前に返される Last-Modify です。サーバーは If-Modify-Since を受信すると、リソースの最終変更時刻に基づいてキャッシュがヒットしたかどうかを判断します。

キャッシュにヒットした場合、304 が返され、リソースの内容は返されず、Last-Modify も返されません。

欠点:

リソースが短期間に変更された場合、Last-Modified は変更されません。

周期的な変化。このリソースがサイクル内で元の状態に変更された場合、キャッシュできると考えられますが、Last-Modified はキャッシュできるとは考えないため、ETag が存在します。

    ETag/If-None-Match
  • は Last-Modify/If-Modify-Since とは異なります。 Etag/If-None-Match はチェック コードを返します。 ETag は各リソースが一意であることを保証でき、リソースが変更されると ETag も変更されます。サーバーは、ブラウザーから送信された If-None-Match 値に基づいてキャッシュがヒットしたかどうかを判断します。
Last-Modified との違いは、サーバーが 304 Not Modified 応答を返すと、ETag が再生成されているため、ETag が以前の状態から変更されていない場合でも、ETag が応答ヘッダーで返されることです。前回のもの。

Last-Modified と ETag は併用できます。サーバーは最初に ETag を検証します。一貫性がある場合は、Last-Modified の比較を続け、最終的に 304 を返すかどうかを決定します。

#概要

ブラウザがすでにアクセスしているリソースにアクセスするときの手順は次のとおりです。

1. まず、強力なキャッシュがヒットするかどうかを確認します。ヒットした場合は、キャッシュを直接使用します。2. 強力なキャッシュがヒットしない場合は、確認するためにサーバーにリクエストが送信されます。ヒットしたら? ネゴシエート キャッシュ

3. ネゴシエーション キャッシュがヒットした場合、サーバーは 304 を返し、ローカル キャッシュが使用できることをブラウザに伝えます

4. ネゴシエーション キャッシュがヒットした場合、サーバーはブラウザに 304 を返します。ヒットしない場合、サーバーは新しいリソースをブラウザに返します

13.什么是浏览器的同源策略,以及跨域?

同源策略

同源策略是浏览器的一种自我保护行为。所谓的同源指的是:协议,域名,端口均要相同

浏览器中大部分内容都是受同源策略限制的,但是以下三个标签不受限制:

<img  src="..." / alt="これらのブラウザ インタビューの質問を見てください。何問正しく答えることができますか?" >
<link href="..." />
<script src="..."></script>

跨域

跨域指的是浏览器不能执行其它域名下的脚本。它是由浏览器的同源策略限制的。

你可能会想跨域请求到底有没有发送到服务器?

事实上,跨域请求时能够发送到服务器的,并且服务器也能过接受的请求并正常返回结果,只是结果被浏览器拦截了。

跨域解决方案(列出几个常用的)

  • JSONP

它主要是利用script标签不受浏览器同源策略的限制,可以拿到从其他源传输过来的数据,需要服务端支持。

优缺点:

兼容性比较好,可用于解决主流浏览器的跨域数据访问的问题。缺点就是仅支持get请求,具有局限性,不安全,可能会受到XSS攻击。

思路:

  • 声明一个回调函数,其函数名(如show)当做参数值,要传递给跨域请求数据的服务器,函数形参为要获取目标数据(服务器返回的data)。
  • 创建一个<script></script>标签,把那个跨域的API数据接口地址,赋值给script的src,还要在这个地址中向服务器传递该函数名(可以通过问号传参:?callback=show)。
  • 服务器接收到请求后,需要进行特殊的处理:把传递进来的函数名和它需要给你的数据拼接成一个字符串,例如:传递进去的函数名是show,它准备好的数据是show('南玖')
  • 最后服务器把准备的数据通过HTTP协议返回给客户端,客户端再调用执行之前声明的回调函数(show),对返回的数据进行操作。
// front
function jsonp({ url, params, callback }) {
  return new Promise((resolve, reject) => {
    let script = document.createElement(&#39;script&#39;)
    window[callback] = function(data) {
      resolve(data)
      document.body.removeChild(script)
    }
    params = { ...params, callback } // wd=b&callback=show
    let arrs = []
    for (let key in params) {
      arrs.push(`${key}=${params[key]}`)
    }
    script.src = `${url}?${arrs.join(&#39;&&#39;)}`
    document.body.appendChild(script)
  })
}
jsonp({
  url: &#39;http://localhost:3000/say&#39;,
  params: { wd: &#39;wxgongzhonghao&#39; },
  callback: &#39;show&#39;
}).then(data => {
  console.log(data)
})
// server 借助express框架
let express = require(&#39;express&#39;)
let app = express()
app.get(&#39;/say&#39;, function(req, res) {
  let { wd, callback } = req.query
  console.log(wd) // Iloveyou
  console.log(callback) // show
  res.end(`${callback}(&#39;关注前端南玖&#39;)`)
})
app.listen(3000)

上面这段代码相当于向http://localhost:3000/say?wd=wxgongzhonghao&callback=show这个地址请求数据,然后后台返回show('关注前端南玖'),最后会运行show()这个函数,打印出'关注前端南玖'

  • 跨域资源共享(CORS)

CORS(Cross-Origin Resource Sharing)跨域资源共享,定义了必须在访问跨域资源时,浏览器与服务器应该如何沟通。CORS背后的基本思想是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是失败。

CORS 需要浏览器和后端同时支持。IE 8 和 9 需要通过 XDomainRequest 来实现

浏览器会自动进行 CORS 通信,实现 CORS 通信的关键是后端。只要后端实现了 CORS,就实现了跨域。

服务端设置 Access-Control-Allow-Origin 就可以开启 CORS。 该属性表示哪些域名可以访问资源,如果设置通配符则表示所有网站都可以访问资源。

虽然设置 CORS 和前端没什么关系,但是通过这种方式解决跨域问题的话,会在发送请求时出现两种情况,分别为简单请求复杂请求

简单请求: (满足以下两个条件,就是简单请求)

1.请求方法为以下三个之一:

  • GET
  • POST
  • HEAD

2.Content-Type的为以下三个之一:

  • text-plain
  • multiparty/form-data
  • application/x-www-form-urlencoded

复杂请求:

不是简单请求那它肯定就是复杂请求了。复杂请求的CORS请求,会在正式发起请求前,增加一次HTTP查询请求,称为预检 请求,该请求是option方法的,通过该请求来知道服务端是否允许该跨域请求。

Nginx反向代理

Nginx 反向代理的原理很简单,即所有客户端的请求都必须经过nginx处理,nginx作为代理服务器再将请求转发给后端,这样就规避了浏览器的同源策略。

14.说说什么是XSS攻击

什么是XSS?

XSS 全称是 Cross Site Scripting,为了与css区分开来,所以简称XSS,中文叫作跨站脚本

XSS是指黑客往页面中注入恶意脚本,从而在用户浏览页面时利用恶意脚本对用户实施攻击的一种手段。

XSS能够做什么?

  • 窃取Cookie
  • 监听用户行为,比如输入账号密码后之间发给黑客服务器
  • 在网页中生成浮窗广告
  • 修改DOM伪造登入表单

XSS实现方式

  • 存储型XSS攻击
  • 反射型XSS攻击
  • 基于DOM的XSS攻击

如何阻止XSS攻击?

对输入脚本进行过滤或转码

对用户输入的信息过滤或者转码,保证用户输入的内容不能在HTML解析的时候执行。

利用CSP

该安全策略的实现基于一个称作 Content-Security-Policy的HTTP首部。(浏览器内容安全策略)它的核心思想就是服务器决定浏览器加载那些资源。

  • 限制加载其他域下的资源文件,这样即使黑客插入了一个 JavaScript 文件,这个 JavaScript 文件也是无法被加载的;
  • 禁止向第三方域提交数据,这样用户数据也不会外泄;
  • 提供上报机制,能帮助我们及时发现 XSS 攻击。
  • 禁止执行内联脚本和未授权的脚本;

利用 HttpOnly

由于很多 XSS 攻击都是来盗用 Cookie 的,因此还可以通过使用 HttpOnly 属性来保护我们 Cookie 的安全。这样子的话,JavaScript 便无法读取 Cookie 的值。这样也能很好的防范 XSS 攻击。

通常服务器可以将某些 Cookie 设置为 HttpOnly 标志,HttpOnly 是服务器通过 HTTP 响应头来设置的,下面是打开 Google 时,HTTP 响应头中的一段:

set-cookie: NID=189=M8l6-z41asXtm2uEwcOC5oh9djkffOMhWqQrlnCtOI; expires=Sat, 18-Apr-2020 06:52:22 GMT; path=/; domain=.google.com; HttpOnly

对于不受信任的输入,可以限制输入长度

15.说说什么是CSRF攻击?

什么是CSRF攻击?

CSRF 全称 Cross-site request forgery,中文为跨站请求伪造 ,攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。 CSRF攻击就是黑客利用用户的登录状态,并通过第三方站点来干一些嘿嘿嘿的坏事

几种常见的攻击类型

1.GET类型的CSRF

GET类型的CSRF非常简单,通常只需要一个HTTP请求:

 <img  src="http://bank.example/withdraw?amount=10000&for=hacker"  alt="これらのブラウザ インタビューの質問を見てください。何問正しく答えることができますか?" >

在受害者访问含有这个img的页面后,浏览器会自动向http://bank.example/withdraw?account=xiaoming&amount=10000&for=hacker发出一次HTTP请求。bank.example就会收到包含受害者登录信息的一次跨域请求。

2.POST类型的CSRF

这种类型的CSRF利用起来通常使用的是一个自动提交的表单,如:

 <form action="http://bank.example/withdraw" method=POST>
    <input type="hidden" name="account" value="xiaoming" />
    <input type="hidden" name="amount" value="10000" />
    <input type="hidden" name="for" value="hacker" />
</form>
<script> document.forms[0].submit(); </script>

访问该页面后,表单会自动提交,相当于模拟用户完成了一次POST操作。

3.链接类型的CSRF

链接类型的CSRF并不常见,比起其他两种用户打开页面就中招的情况,这种需要用户点击链接才会触发。这种类型通常是在论坛中发布的图片中嵌入恶意链接,或者以广告的形式诱导用户中招,攻击者通常会以比较夸张的词语诱骗用户点击,例如:

  <a href="http://test.com/csrf/withdraw.php?amount=1000&for=hacker" taget="_blank">
  重磅消息!!
  <a/>

由于之前用户登录了信任的网站A,并且保存登录状态,只要用户主动访问上面的这个PHP页面,则表示攻击成功。

CSRF的特点

  • 攻击一般发起在第三方网站,而不是被攻击的网站。被攻击的网站无法防止攻击发生。
  • 攻击利用受害者在被攻击网站的登录凭证,冒充受害者提交操作;而不是直接窃取数据。
  • 整个过程攻击者并不能获取到受害者的登录凭证,仅仅是“冒用”。
  • 跨站请求可以用各种方式:图片URL、超链接、CORS、Form提交等等。部分请求方式可以直接嵌入在第三方论坛、文章中,难以进行追踪。

CSRF通常是跨域的,因为外域通常更容易被攻击者掌控。但是如果本域下有容易被利用的功能,比如可以发图和链接的论坛和评论区,攻击可以直接在本域下进行,而且这种攻击更加危险。

防护策略

ハッカーは被害者の cookie を使用してサーバーの信頼を騙すことしかできませんが、ハッカーは **"cookie"** の取得に頼ることはできませんし、**"cookie" のコンテンツを見ることもできません。さらに、ブラウザの「同一生成元ポリシー」制限により、ハッカーはサーバーから返された結果を解析できません。

これは、保護したいオブジェクトはデータ変更を直接生成できるサービスであり、データを読み取るサービスの場合は

CSRF を保護する必要がないことがわかります。保護の鍵は 「ハッカーが偽造できない情報をリクエストに含める」

独自の検出

ほとんどの CSRF はサードパーティの Web サイトからのものであるため、外部ドメイン (または信頼できないドメイン名) が当社にリクエストを送信することを直接禁止しています。

では、問題は、リクエストが外部ドメインからのものであるかどうかをどのように判断するかということです。

HTTP プロトコルでは、各非同期リクエストには、ソース ドメイン名をマークするために使用される 2 つのヘッダーが含まれます:

    Origin Header
  • Referer Header
これら 2 つのヘッダーは、ほとんどの場合、ブラウザーがリクエストを開始するときに自動的に取り込まれ、フロントエンドでコンテンツをカスタマイズすることはできません。サーバーは、これら 2 つのヘッダー内のドメイン名を解析することで、リクエストのソース ドメインを判断できます。

Origin ヘッダーを使用してソース ドメイン名を決定する

一部の CSRF 関連のリクエストでは、Origin フィールドがリクエストされたヘッダーに含まれます。このフィールドには、要求されたドメイン名 (パスとクエリを除く) が含まれます。

Origin が存在する場合は、Origin のフィールドを使用してソース ドメイン名を確認するだけです。

ただし、次の 2 つのケースでは、オリジンは存在しません:

  • IE11 同一オリジン ポリシー: IE 11 は、クロスサイト CORS リクエスト ヘッダーにオリジンを追加しませんの場合でも、Referer ヘッダーが唯一の識別子になります。最も根本的な理由は、IE 11 の同一オリジンの定義が他のブラウザーと異なることです。主な違いは 2 つあります。MDN Same-origin_policy#IE_Exceptions
  • 302 リダイレクトを参照してください。 :
  • オリジンは、他のソースからの機密情報とみなされる可能性があるため、302 リダイレクト後のリダイレクトされたリクエストには含まれません。 302 リダイレクトの場合、URL は新しいサーバーにダイレクトされるため、ブラウザはオリジンを新しいサーバーに漏洩することを望みません。
リファラー ヘッダーを使用してソース ドメイン名を決定する

HTTP プロトコルによると、HTTP ヘッダーにはリファラーと呼ばれるフィールドがあり、 HTTPリクエストの送信元アドレス。 Ajax リクエスト、画像やスクリプトなどのリソース リクエストの場合、リファラーはリクエストを開始するページ アドレスです。ページ ジャンプの場合、Referer はページ履歴を開いた前のページのアドレスです。したがって、Referer 内のリンクの Origin 部分を使用して、リクエストのソース ドメイン名を知ることができます。

このメソッドは確実ではありません。Referer の値はブラウザによって提供されます。HTTP プロトコルには明確な要件がありますが、ブラウザごとに Referer の実装が異なる可能性があり、ブラウザが適切に実装するという保証はありません。独自のセキュリティホールはありません。 Referer 値を検証する方法は、セキュリティを確保するためにサードパーティ (ブラウザなど) に依存するため、理論的にはあまり安全ではありません。場合によっては、攻撃者は要求したリファラーを非表示にしたり、変更したりする可能性があります。

2014 年、W3C の Web アプリケーション セキュリティ ワーキング グループは、ブラウザがリファラーを送信する方法について詳細な規定を定めたリファラー ポリシーの草案をリリースしました。現時点では、ほとんどの新しいブラウザーがこのドラフトをサポートしており、最終的に Web サイトのリファラー戦略を柔軟に制御できるようになりました。新しいバージョンのリファラー ポリシーでは、リファラーなし、ダウングレード時リファラーなし、オリジンのみ、クロスオリジン時のオリジン、および安全でない URL の 5 つのリファラー ポリシーが規定されています。既存の 3 つの戦略 (never、default、always) は、新しい標準では名前が変更されました。対応関係は次のとおりです。

#ポリシー名属性値(新)属性値(旧)リファラーなしno-Referrer決してしないダウングレード時にリファラーなしno-Referrer-when-downgradedefaultOrigin Only(同じまたは厳密)originorigin (厳密)origin-when-crossorigin安全でない URL##

根据上面的表格因此需要把Referrer Policy的策略设置成same-origin,对于同源的链接和引用,会发送Referer,referer值为Host不带Path;跨域访问则不携带Referer。例如:aaa.com引用bbb.com的资源,不会发送Referer。

设置Referrer Policy的方法有三种:

  • 在CSP设置

  • 页面头部增加meta标签

  • a标签增加referrerpolicy属性

上面说的这些比较多,但我们可以知道一个问题:攻击者可以在自己的请求中隐藏Referer。如果攻击者将自己的请求这样填写:

 <img  src="http://bank.example/withdraw?amount=10000&for=hacker" referrerpolicy="no-referrer" alt="これらのブラウザ インタビューの質問を見てください。何問正しく答えることができますか?" >

那么这个请求发起的攻击将不携带Referer。

另外在以下情况下Referer没有或者不可信:

1.IE6、7下使用window.location.href=url进行界面的跳转,会丢失Referer。

2.IE6、7下使用window.open,也会缺失Referer。

3.HTTPS页面跳转到HTTP页面,所有浏览器Referer都丢失。

4.点击Flash上到达另外一个网站的时候,Referer的情况就比较杂乱,不太可信。

无法确认来源域名情况

当Origin和Referer头文件不存在时该怎么办?如果Origin和Referer都不存在,建议直接进行阻止,特别是如果您没有使用随机CSRF Token(参考下方)作为第二次检查。

如何阻止外域请求

通过Header的验证,我们可以知道发起请求的来源域名,这些来源域名可能是网站本域,或者子域名,或者有授权的第三方域名,又或者来自不可信的未知域名。

我们已经知道了请求域名是否是来自不可信的域名,我们直接阻止掉这些的请求,就能防御CSRF攻击了吗?

且慢!当一个请求是页面请求(比如网站的主页),而来源是搜索引擎的链接(例如百度的搜索结果),也会被当成疑似CSRF攻击。所以在判断的时候需要过滤掉页面请求情况,通常Header符合以下情况:

Accept: text/html
Method: GET

但相应的,页面请求就暴露在了CSRF的攻击范围之中。如果你的网站中,在页面的GET请求中对当前用户做了什么操作的话,防范就失效了。

例如,下面的页面请求:

GET https://example.com/addComment?comment=XXX&dest=orderId

注:这种严格来说并不一定存在CSRF攻击的风险,但仍然有很多网站经常把主文档GET请求挂上参数来实现产品功能,但是这样做对于自身来说是存在安全风险的。

另外,前面说过,CSRF大多数情况下来自第三方域名,但并不能排除本域发起。如果攻击者有权限在本域发布评论(含链接、图片等,统称UGC),那么它可以直接在本域发起攻击,这种情况下同源策略无法达到防护的作用。

综上所述:同源验证是一个相对简单的防范方法,能够防范绝大多数的CSRF攻击。但这并不是万无一失的,对于安全性要求较高,或者有较多用户输入内容的网站,我们就要对关键的接口做额外的防护措施。

CSRF Token

前面讲到CSRF的另一个特征是,攻击者无法直接窃取到用户的信息(Cookie,Header,网站内容等),仅仅是冒用Cookie中的信息。

而CSRF攻击之所以能够成功,是因为服务器误把攻击者发送的请求当成了用户自己的请求。那么我们可以要求所有的用户请求都携带一个CSRF攻击者无法获取到的Token。服务器通过校验请求是否携带正确的Token,来把正常的请求和攻击的请求区分开,也可以防范CSRF的攻击。

利用Cookie的SameSite属性

可以看看MDN对此的解释:

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Set-Cookie/SameSite

SameSite可以设置为三个值,StrictLaxNone

  • Strict模式下,浏览器完全禁止第三方请求携带Cookie。比如请求sanyuan.com网站只能在sanyuan.com域名当中请求才能携带 Cookie,在其他网站请求都不能。

  • Lax模式,就宽松一点了,但是只能在 get 方法提交表单况或者a 标签发送 get 请求的情况下可以携带 Cookie,其他情况均不能。

  • 在None模式下,Cookie将在所有上下文中发送,即允许跨域发送。

更多编程相关知识,请访问:编程入门!!

#Origin When Cross Origin
- 安全でないURL
常に

以上がこれらのブラウザ インタビューの質問を見てください。何問正しく答えることができますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。