Webアプリの形式でサイトを機能させる方法(説明が不十分なプライベートソリューションの例には誰も興味がありません)

おそらくこれは、「 iOS用のサイトとAJAX Webアプリケーションの適応の違い 」というトピックと、そこからの私のコメントからのアイデアの発展の一種の継続です。



トピックは古いですが、多くの人にとってはまだ関連しています。 一般的に、目標は普遍的なソリューションを考え出すことではなく、大きな変更に頼らずに1つの特定のサイトをWebアプリとして機能させる必要があるため、内部には多くの詳細があります。 一般的に、いつものように、誰が気にします-カットの下で、おそらく残りは通り過ぎます。



そのため、導入タスクと問題を示します.Webサイト(通常、特別なものは何もありません)をWebアプリのように動作させ、Safariにジャンプしたり、クライアントがどのページにいて、そこで何をしていたかを覚えておく必要があります。 これまで読んだ人は、何もせずに上記のすべてを達成することを妨げる問題をよく知っていると思います:Safariで通常のリンクが開き、Webアプリから別のアプリケーションに切り替えるか最小化すると、開いたときに開きます表示されるページは、実際にはWebアプリとして保存されます-最も頻繁に使用されるメインアプリです。



一般に、空のタスク:1)Safariでリンクがスローされないようにします。 2)セッションを思い出深いものにする。 3)開いているページを記憶させる。 元のトピックとは異なり、タスクをこの順序で設定しますが、以下ではその理由が明確になります。



決定するために追われました!



Safariでリンクが吐き出されないようにする



この問題は長い間解決されてきました。 JSのリンク上のすべてのクリックをキャッチし、それらをlocation.assign()でやり直すだけです。 。



一般に、新しいものは何も思いつきませんでした。少し拡張する必要がありました。1)スタンドアロンモードでのみ適用されます。 2)リンクが(外部)(別のホストと)の場合、適用されません(Safariが開きます)。 3)リンクがアンカー(#some-shit)の場合、location.hashのみが置換されます。



つまり、このハンドラーをスタンドアロンでオンにし、hrefを含むリンクを要求してから、特定のケースでデバッグします。 コードはここにはありません。1行と、誰にとっても面白くない多くの特殊性があるからです。



セッションは覚えておく必要があります



もっと複雑です。 問題は、Webアプリを再起動すると、Cookieが送信されず、Cookieが存在しないということです-セッションは新規です。 バスケットは失われました。 一般的に、悪い。 元のトピックでは、JSから直接Cookieの読み取りと書き込みを行うソリューションがありましたが、コメントで書いたように、これは現代の現実ではあまりうまくいきません-セッションCookieはhttpOnlyになりました。つまり、JSには一切表示されません。



少し異なる方法で決定します。識別子もlocalStorageに保存しますが、サーバー側からセッションを比較および管理し、ajaxを介してこれらすべてを調整します。 JSでは、このソーセージのようなものを作成します(スタンドアロンモード専用):



$.post('/super-puper-server-script.json', {'sid': localStorage.getItem('sid')}, function(data) { localStorage.setItem('sid', data.sid); if (data.loc) window.location = data.loc; });
      
      







localStorageから現在のsid値を送信し、返される内容を保存します。場所がまだ返される場合は、それを通過します。 したがって、すべてのロジックがサーバーに送信され、そこでセッション識別子の現在の値を取得できます。さらに重要なことは、どの識別子が正しいかを理解できることです。



(注:私が使用しているYiiでは、セッションデータが保存されている間、セッション識別子は承認中に変更されます。つまり、ユーザーが承認中にバスケット(および他のセッションデータ)を保存できるようにすると同時に、一般的に承認を維持します。実際には、localStorageのセッション識別子をセッションに置き換えないでください。)



内部では、サーバー側では、すべてが非常に簡単です。 私は悲惨だからではなく、コードを持っていませんが、アルゴリズム自体を説明すれば、叫ぶ代わりに自分で簡単に任意の言語でコーディングできるように思えます。 PHP-登録解除!」



アルゴリズムは次のようなものです:JSから識別子を取得し、Cookieから識別子を取得し、比較(例外、たとえば、承認、または識別子の別の正当な変更)をチェックし、異なる場合はJSから適用します。 応答として、現在のセッションにある識別子を送信します。 何かが変更された場合は、現在の場所を回答に追加します。これにより、ページがリロードされ、セッションデータが既に適用されます。



ページを覚えておく必要があります



ここにルアーがあります。なぜセッションの前にこの(全体としてより重要な)問題を解決しなかったのですか。 まず、私は間違いなく元のトピックのアプローチが好きではありません-すべてのクリックをlocalStorageに保存し、そこから復元します。 ローカルに変更されますが、localStorageには保存されないリダイレクト、ジャンプ、フォームがあるため、これは悪いことです。 これは悪いことです。なぜなら、他の場所と同様に、JSで例外を作成する必要があるからです。



そして、それは私に夜明けを告げました-私たちはセッションを復元するためにそのような困難で学びました、なぜ場所をそこに保存しませんか? そして、すべてが非常に美しく適切であることが判明しました。まず、セッションを復元する(Webアプリを再起動する)場合にのみ場所を復元するのが理にかなっています。 第二に、現在のページとして正確に保存するもの(および保存しないもの)を制御する機会が増えます。 最後に、このアプローチでは、正しいセッションデータを適用し、ユーザーに何を見ているかを示すために、ページを1回だけ再読み込みできます。



以下は、サーバー側のコードの例です。もちろん、PHPの場合も同じです。



 $sid = $_POST['sid']; $loc = abs2rel($_SERVER['HTTP_REFERER']); $resid = false; if (!empty($sid) && !empty($_COOKIE['PHPSESSID']) && $sid != $_COOKIE['PHPSESSID']) { session_id($sid); $resid = true; } session_start(); $reloc = ($resid && isset($_SESSION['loc'])) ? $_SESSION['loc'] : false; $_SESSION['loc'] = $loc; return ['sid' => session_id(), 'loc' => $reloc];
      
      







コードに関するコメント:当然、これはすべてajaxを介したPOSTでのみ始まります。 識別子間の違いをチェックする際に、識別子を(合法的に)変更する必要がある場合に条件を追加できます。 セッションで場所を保存する前に、一部のチェックを除外することもできます。 返されたハッシュは自動的にJSONに変換されます。



たぶん何かを見逃したかもしれませんが、全体としては非常にうまく機能します。 さて、そして明らかに、わかりやすい記事を書くことは私のものではありません。 それは無秩序にそして不可解に起こりましたが、それはそのままです...



All Articles