あなたのアプリケーションの問題を見つけるためにユーザーの要求や応答をキャプチャ


著者によってFernando Doglio
クライアントコード内のエラーは、JavaScriptコードのどれも動作しないため、空白の画面を取得したときのように明白ではありません.
時々あなたのアプリで問題は、あなたのユーザーが取ることができる特定のアクションを与えられた、あなたが誤ってサーバーに要求を形成していることです.
クライアントコードが動作すると、コンソール上の任意のJSエラーを取得しませんが、あなたのバックエンドは、あなたがそれを送っているものを本当に好きではありません.
OpenReplayを使用すると、標準のセッション再生の一部としてクライアントサーバーの通信をキャプチャし、後でそれを確認することができます.
それで、我々がそれをすることができる方法と我々がそれから得ることができるどんな種類の利益を見てみましょう.

サンプルアプリ


このハウツーの目的のために、私は使用する単純な反応アプリケーションを作成しましたBored API . これは、いくつかのパラメータに基づいてランダムなアクティビティの提案を返す非常に単純なAPIです.
そこで私は「i - bored - app」を作りました.

そして、あなたはそれがNetlifyover here , または、あなたが詳細にそれを見るためにコードをチェックアウトしたいならば、それは完全に利用できますGitHub .
このアプリケーションはSearchForm これらの2つのフィールドとボタンを表示するのに注意してください、そして、APIに実際の要求を送ってください.
Suggestion コンポーネントは、単に良い探しボックス内の提案をレンダリングします.
私は最初の1つに焦点を当てるつもりです、それはfetch 関数.それが何であるかについて理解するために、成分を簡単に見ましょう.

SearchFormコンポーネントのコード


これは複雑なコンポーネントではありませんが、この特定のユースケースに特に関連するセクションがありますので、簡単に見てみましょう.
import { Container, Col, Form, Row, Button } from 'react-bootstrap';

const SearchForm = ({setResult, fetcher}) => {
const getSomething = async (evt) => {
    evt.preventDefault()
    let form = evt.target

    const API_URL = "/api/activity?"
    let getParams = {}
    if(form.participants.value !== '') {
      getParams.participants = form.participants.value
    }

    if(form.priceRange.value !== '') {
      let prices = form.priceRange.value.split("_")
      getParams.minprice = prices[0]
      getParams.maxprice = prices[1]
    }

    let results = await fetcher(API_URL + new URLSearchParams(getParams), {
        mode: 'no-cors'
    })
    setResult(await results.json())

    return false
  }


    return (
        <Container>
        <Form onSubmit={getSomething}>
          <Row>
            <Col>
          <Form.Group controlId='participants' >
            <Form.Label>Participants</Form.Label>
            <Form.Control type='text' name="totalParticipants" placeholder='Leave empty if you dont care...'></Form.Control>
          </Form.Group>
          </Col>
            <Col>
          <Form.Group controlId='priceRangeId'>
            <Form.Label>Price range</Form.Label>
            <Form.Select name="priceRange" >
              <option value="" >Select one or leave empty if you dont care</option>
              <option value="0.0">Free</option>
              <option value="0.1_0.5">Cheap</option>
              <option value="0.6_1.0">Expensive</option>
            </Form.Select>
          </Form.Group>
          </Col>
          </Row>
          <Row className='m-3'>
            <Col>
            <Form.Group>
              <Button variant="primary" type="submit">Get me something!</Button>
            </Form.Group>
            </Col>
          </Row>
        </Form>
      </Container>
    )
}

export default SearchForm
注意getSomething 関数は、魔法のほとんどが発生する場所です.フォームのSubmitイベントが発生すると、関数が呼び出されます.
そのとき、この関数は、target プロパティ.我々は、単にフィルタ(入力フィールドとドロップダウン)の各々から値を捕えて、それからfetch 関数.
URLが直接BoredAPIのエンドポイントを対象としていないことに注意してください.これは、要求するために動作し、Corsの制限のためにブロックされていないため、私はバックエンドのすべての要求をリダイレクトするプロキシを構成しているから/api を返します.
あなたがコードを見た今、あなたはフェッチプラグインなしでOpenReplayのTrackerをインストールするなら、何を得るかを見ましょう.

OpenReplayで定期的なデータのキャプチャ


この例については、パッケージのNPMバージョンを使用するつもりです.もしそうする方法がわからないなら、チェックアウトしてくださいthe docs そして戻ってください.

これは、プラグインを使用せずにセッションリプレイのUIです.どのように私はすでに“ネットワーク”タブを選択した下半分に注意してください、しかし、それが行われている要求を表示している間、私がクリックしたもの(最後の1つ)でも、それらについての詳細はありません.これは十分ではないでしょう.
それで、我々は何をすることができますか?
フェッチプラグインをインストールして設定しましょう.

OpenReplayのフェッチプラグインの設定


我々のために幸運な、これを行うことは、メイントラッカーをインストールするよりも簡単です.
NPM版を使いますので、以下のコマンドでインストールします.
npm i @openreplay/tracker-fetch
それから、我々は、我々のコードに1行のコードを加えることによってそれを使うことができますApp.js ファイル.念頭に置いて私のアプリは、スパである場合は、場合ではない、レビューをしてくださいthe documentation それをどのように設定するかを理解するために.
次に、次の行を追加します.
const fetch = tracker.use(trackerFetch({}))
トラッカーが新しいバージョンを返すということを意味するデフォルトオプションを使いますfetch 関数.あなたが今どこにでもそれを使用することができます.これはあなたの自由だけではなく、それらのすべての特定の要求を追跡することができます.あなたのアプリケーションが十分に複雑であり、複数の異なる要求を持っている場合に便利です.
私たちのケースではそうではないので、私はfetch 関数は、SearchForm コンポーネントは、コードに戻って、あなたはプロップと呼ばれる通知されますfetcher ).
それは私たちが行う必要がある、今、変更を展開し、アプリケーションをテストし、タブを閉じ、数分を待つ.セッションはすぐに表示される必要がありますし、“再生”ボタンを押すことができます.

クライアント・サーバ通信の検査


この例のために、私がアプリケーションを公開した後に見始めた問題も見てみましょう.
この場合、警告ボックスに注意してください.

コード化されたdevとして、私はそれをテストするために何を知っているとバグがどこにあるかを理解する.しかし、ユーザとして、エラーは本当に私に多くのことを言っていません、そして、私はdevチームが理解する方法でこれを伝えることができないかもしれません.
その代わりに、ユーザーとして、私は単に彼らのアプリケーションについての会社に文句を言うことができます、そして、あなたはアプリケーションのために責任がある開発者が私のセッションを見て、クライアントが送った要求とサーバーからの応答を調べることができるので.

今すぐセッションの再生UIを見てください.クライアントのアプリケーションにフェッチプラグインの追加では、新しい“フェッチ”検査官が有効になっています.をクリックすると、すべての要求がなされることがわかります.はい、この時間を1つをクリックすると、必要な詳細を取得します.
我々が今しなければならないすべては、我々がエラー応答を得て、作られている要求を見る瞬間を見つけることです.チャンスは、要求の詳細の中の問題が表示されます.
私たちの場合、エラーは「引数のエラーのために問い合わせに失敗しました」と言います、ドロップダウンの「自由な」オプションを選ぶとき、我々は有効な要求を送っていません.その詳細を見てみましょう.

あなたはその問題を見ることができますか.お手伝いしましょう

はい、私は送信するundefined の値としてmaxprice 属性.私は、私の論理でそれを完全に逃して、要求を調べる間、それを拾いました.
もちろん、問題がどこにあるのかわかりましたが、このプロセスのおかげで、私は非常に詳細なエラーレポートを上げるか、直接開発者が自分自身をテストし、問題を再現することなく問題を解決し、解決することができました.

テストにプライバシーを置く


よし、この例をさらに少し考えてみましょう.このリクエストのために私のユーザの電話番号も必要とします.私は明らかにしないでください、ちょっとちょっと私をちょっとユーモアしてください.
フィールドをフォームに追加し、その値を取得するコードを更新し、リクエストの一部として送信します.
フォームのHTMLは、新しいCol 以下のような要素:
<!-- previous code -->
<Col>
    <Form.Group controlId='phoneNumber'>
        <Form.Label>Phone Number</Form.Label>
        <Form.Control type='number' name="phoneNumber" placeholder='Enter your phone number here please'></Form.Control>
    </Form.Group>
</Col>
<!-- rest of the code -->
このフィールドの内容を実際のリクエストに追加するには、1行のコードが必要です.
getParams.phonenumber = form.phoneNumber.value
さて、私たちがこの新しいコードを使用して、OpenReplayでセッションを捕えるならば、何が起こりますか?
さて、二つ
  • あなたが自動的に電話番号のフィールドのコンテンツを消毒し、それを見て誰にも表示されません見て実際のリプレイ.
  • しかし、プラグインによってキャプチャされた要求情報は、値を表示します.
  • 以下のスクリーンショットは、私がちょうど説明したものです.

    画面の右側のセクションでは、完全な電話番号を見ることができます.これは通常のトラッカーは、数値フィールドである電話番号のフィールドを理解することができますが、それは発生した場合には、その場合は、番号は個人情報を表す入力をキャプチャしません.しかし、要求側では、開発者がデータ、またはパラメータの名前さえ何もできなかったので、私たちは本当にその仮定をすることができません.
    それで、質問はそうです:我々は、このプラグインで我々のユーザーのプライバシーを保護することができますか?
    そして、答えは、私は報告する満足している、そうです.

    リクエストデータを処理する


    あなたがこの記事の始めに戻るならば、私がプラグインを構成するとき、あなたはデフォルトオプションを使用するのを見ます.ただし、これらのオプションの一部として、データを処理するためのコールバックを指定できます.このコールバックは、リクエストと応答オブジェクトの両方を持つ単一の属性を受け取ります.その後、それらを編集することを選択することができますが、彼らは実際のリクエストに影響を与えませんが、データをOpenReplay UIに表示される方法を変更します.
    例えば、“phonenumber”属性を変更して、その情報を漏らすのを避けるために数を削除したいとしましょう.これは次のようにします.
    const fetch = tracker.use(trackerFetch({
      sanitiser: (data) => {
        data.url = data.url.replace(/phonenumber=([0-9]+)/, "phonenumber=XXXXXX")
        return data
      }
    }))
    
    ご覧のように、変更は簡単です.この属性の数だけを置き換えるので、この要求はUIのようになります.

    今すぐあなたのユーザーのデータをもう一度確保されます.
    セッションリプレイは、問題がどこにあるかを示す直接のエラーメッセージがない(コンソール上のエラーメッセージのように)それらのケースでさえ、バグを特定する素晴らしいツールです.
    さらに、あなたは、バグを検証するために自分自身をプロセスを通過することなく、無限の再生可能性を取得し、彼らは無視する可能性がありますが、彼らは無関係だと思うので、報告していないことを含むユーザーアクションの完全な詳細を取得します.
    あなたがフェッチプラグインまたはトラッカー自身をセットアップするどんな問題も持っているならば、我々の上で我々に手を差し伸べてくださいDiscord community そして、直接我々のDEVSを尋ねてください!