2

私はvarnish+esiを使用して、RESTFulAPIから外部のjsonコンテンツを返しています。この手法により、リクエストごとにWebサーバーのリソースを使用せずに、リクエストを管理してデータを更新できます。

例えば:

<head>
.... 
<script> 
 var data = <esi:include src='apiurl/data'>;
</script>
...

インクルード後、esiワニスは次のように戻ります。

 var data = {attr:1, attr2:'martin'};

これは正常に機能しますが、APIがエラーを返す場合、この手法は解析エラーを生成します。

var data = <html><head><script>...api js here...</script></head><body><h1 ... api html ....

隠しdivを使用してこの問題を解決し、エラーを解析してキャッチしました。

...
<b id=esi-data style=display:none;><esi:include src='apiurl/data'></b>
<script>
  try{
    var data = $.parseJSON($('#esi-data').html());
  }catch{ alert('manage the error here');}
....

スクリプトタイプtext/esiも使用してみましたが、ブラウザはスクリプトタグ(wtf)内にhtmlをレンダリングします。例:

<script id=esi-data type='text/esi'><esi:include src='apiurl/data'></script>

質問

タグをラップして、ブラウザがタグを解析しないようにする理由はありますか?

4

5 に答える 5

4

私がコメントで行った提案を拡張してみましょう。iframeそれはあなたの考えとはまったく異なります。

アプローチは、すでに行っていることとほぼ同じですが、のような通常のHTML要素を使用する代わりにdiv、を使用しiframeます。

<iframe id="esi-data" src="about:blank"><esi:include src="apiurl/data"></iframe>
var $iframe = $('#esi-data');

try {
    var data = $.parseJSON($iframe.html());
} catch (e) { ... }

$iframe.remove();
#esi-data { display: none; }

これはあなたのソリューションとどう違うのですか?ふたつのやり方:

  1. データ/エラーページは訪問者から本当に隠されています。Aniframeにはコンテンツモデルが埋め込まれています。つまり、<iframe>…&lt;/iframe>タグ内のすべてのコンテンツがDOMで完全に置き換えられますが、を使用して元のコンテンツを取得することもできますinnerHTML

  2. それは有効なHTML5です…ある種。HTML5では、iframe要素内のマークアップはテキストとして扱われます。確かに、フラグメントとして解析できるようになっています。また、フレージングコンテンツのみが含まれていることを意味します(要素は含まれていませscript)が、基本的には、バリデーターとブラウザーによってテキストとして扱われます。

  3. エラーページのスクリプトは実行されません。コンテンツはテキストとして解析され、DOM内で別のドキュメントに置き換えられscriptます。要素が処理される可能性はありません。

実際の動作を見てください。要素を削除した行をコメントアウトしてiframeDOMを調べると、HTMLコンテンツが空のドキュメントに置き換えられていることを確認できます。scriptまた、埋め込みタグは実行されないことに注意してください。

重要iframe:サードパーティが何らかの理由でエラーページに要素を追加した場合でも、このアプローチは機能しなくなる可能性があります。可能性は低いですが、テクニックをこれと組み合わせることで、アプローチをもう少し防弾することができます。解析が終了したときに削除するiframe非表示で囲みます。div

于 2012-08-09T16:47:44.907 に答える
1

ここで、別の試みを行います。

これについてはおそらく最善の解決策がすでにあると思いますが、別の HTML ウィンドウで呼び出すというかなりパフォーマンスの低い方法で回避しesi:insert、サーバーで AJAX を使用しているかのようにコンテンツを取得することしか想像できませんでした。 . おそらくこれに似ていますか?次に、おそらく使用して、取得したコンテンツを確認し、json_decode成功するとエラー JSON 文字列を生成します。

これの最大の欠点は、サーバー自体がクライアントであるかのように別のページが呼び出され、解析されてから送り返されるため、これは非常に消費量が多く、リクエストを遅らせる可能性が高いことです。

私は正直にあなたの現在の解決策に固執します。

于 2012-08-02T16:19:40.033 に答える
1

これは、解決策がまったくないわけではないにしても、真のエレガントな解決策がないかなりトリッキーな問題です

HTML(5) ドキュメントか XHTML(5) ドキュメントかを尋ねました。後者の場合、CDATAセクションを使用してコンテンツをラップし、ソリューションを次のように少し変更できるためです。

...
<b id='esi-data' style='display:none;'>
    <![CDATA[ <esi:include src='apiurl/data'> ]]>
</b>
<script>
    try{
        var data = $.parseJSON($('#esi-data').html());
    }catch{ alert('manage the error here');}
....

クラウドの場合、このソリューションは次の場合に機能します。

  1. XHTML5 を使用していて、
  2. エラーには CDATA セクションが含まれていません( CDATA セクションのネストが不可能であるため)。

あるシリアル化から別のシリアル化への切り替えがオプションかどうかはわかりませんが、質問の意図を明確にしたかったのです。うまくいけば、あなたを助けるでしょう:)。

于 2012-08-08T16:36:09.503 に答える
0
<script>var data = 999;</script>

<script>
data = <esi:include src='apiurl/data'>;
</script>

<script>
if(data == 999) alert("there was an error");
</script>

エラーが発生し、「データ」が JSON でない場合は、javascript エラーがスローされます。次のスクリプト ブロックがそれを取得します。

于 2012-08-07T11:27:25.260 に答える
0

{ "error":"error_code_or_text" }エラー時に JSON を返すように API を変更することはできませんか? インターフェイスで何か意味のあることをして、そのようにした場合にエラーについてユーザーに警告することもできます。

于 2012-08-02T21:10:18.037 に答える