3

フォームの検証には、どこにでもあるjquery validate プラグインを使用しています。フォーム要素に検証ルールを追加するためのメタデータ プラグインの使用をサポートします。

この機能を使用しています。validate でこれらのルールを探すと、要素に対して次の呼び出しが行われます。

$(element).metadata()[meta] 

wheremetaは、それらのルールを保存するプレフィックスです。例えば

<input data-validate="{maxLength: 12}" name='foo'/>

これらの属性を取得するには、meta の値を「validate」に設定します。しかし、ここで重大な問題が!

メタデータ プラグインがデータ属性を json に解析するために行うことは次のとおりです。

var getObject = function(data) {
    if(typeof data != "string") return data;
    data = eval("(" + data + ")"); //oh no!!!!!
    return data;
} 

if ( settings.type == "html5" ) {
    var object = {};
    $( elem.attributes ).each(function() {
        var name = this.nodeName;
        if(name.match(/^data-/)) name = name.replace(/^data-/, '');
        else return true;
        object[name] = getObject(this.nodeValue);
    });
} 

data-*その結果、メタデータはすべての属性を解析し、コンテンツを評価しようとします! これは、json を含まないデータ属性を含めるとすぐに壊れます。

今質問:

メタデータと検証はどちらも「実証済み」のプラグインのようです。これは、人々が一緒に暮らすメタデータ プラグインを使用した場合の既知の副作用ですか?

私は通常、プロジェクトのニーズに合わせてプラグイン コードを変更するのは好きではありませんが、次のいずれかを行う必要があるようです。

  • やみくもに eval を行わないようにメタデータ プラグインを修正し、eval または
  • .data()メタデータ プラグインの代わりに検証プラグインを使用するように修正

また、メタデータプラグインを変更する以外に、これを回避する方法はありますか

報奨金の投稿の編集: 私はこれをより明確にする必要がありました.これがどのように起こったのかについての議論に興味があります. この規模のバグが、標準的な検証プラグインと resig によって書かれたあらゆる場所で使用されているプラ​​グインの両方にどのように存在する可能性があるか。

修正は簡単で、私はすでにそれを適用しています ('meta' が定義されているときに $.data を使用するように検証プラグインを変更することにしました) - ここで 150 ポイントを与えているのは、これがまだ問題である理由についての考えです (または多分そうじゃない!)

4

2 に答える 2

7

あなたが発見したように、「障害」(eval を使用) は検証プラグインではなく、メタデータ プラグインにあります。

リンクしたメタデータ プラグインのバージョンは、実際にはフォークです。jQuery チームには公式リポジトリがあります。コミット履歴を見ると、2007 年以降、実際のコードの更新がないことがわかります。このプラグインは、2011 年 4 月以降、公式に非推奨になりました。

(John Resig は 2008 年 7 月にHTML5 の data- 属性についてブログを書き、 2010 年 10 月にリリースされた1.4.3で jQuery コアのサポートが開始されました。)

したがって、「これがどのように起こったのか」というあなたの質問に対する答えは、プラグインをもう使用していないと思われるということだと思います:-)

(更新:公式」リポジトリは現在、「jQuery Foundation によって孤立したプロジェクト」の下にあります。)

検証プラグインについては、一部のデモとオプションを除いてmeta、ドキュメントにメタデータ プラグインに関する言及が見つかりません。data- 属性のサポートを追加し、メタデータ プラグインを非推奨にする作業が進行中です。そのため、次のバージョンの準備ができたら、メタデータ プラグインを最終的に放棄できることを願っています。

于 2012-07-04T11:02:53.927 に答える
0
data = eval("(" + data + ")"); //oh no!!!!

それを置き換える方法の1つ

data = $.parseJSON(data); // oh yes!!!

実際に .data() メソッドで「データ」を取得すると、それを解析しようとしてうまくいきます。それを使用して要素からデータを取得することをお勧めします。その後、ノードに接続されるキャッシュされたオブジェクトを取得し、属性の値をはるかに高速に提供します。

これは、彼が取得したものすべてを評価しないメタデータ プラグインの分岐バージョンです。これについて知っておくべきことが 1 つあります。JSON のように dict のすべての部分を引用する必要がありますが、必ずしも二重引用符で囲む必要はありません。

{'foo': 'bar', "m": true, "b": 1}; // works
{foo: 'bar', m: true, b: 1}; // won`t work
于 2012-07-02T14:44:18.650 に答える