1

ユーザーが有効な HTML をテキスト フィールドに入力するアプリケーションを作成しています。

テキストフィールド領域を W3C バリデーターにロードしようとする jQuery のボタンがあります。

$('#inspecthtml').on('click', function() {
             var storyhtml = $('#story').text();
             validatorurl= "http://validator.w3.org/#validate_by_input";
             var newWin = open(validatorurl,'Validator','height=600,width=600');
             newWin.onload = function() {
                 newWin.document.getElementById("fragment").value=storyhtml;
             }           
    });

コンソールにエラー メッセージが表示されます (Chrome を使用):

安全でない JavaScript が URL http://api.flattr.com/button/view/?url=http%3A%2F%2Fvalidator.w3.org%2F&title=View%20W3C-Validator%20on%20flattr.com&でフレームにアクセスしようとしています。 URL http://validator.w3.org/#validate_by_inputのフレームから。アクセスされたフレームは「document.domain」を「flattr.com」に設定しましたが、アクセスを要求したフレームは設定しませんでした。アクセスを許可するには、どちらも「document.domain」を同じ値に設定する必要があります。

私はこれをクロスドメインセキュリティに起因すると考えています (安全でない JavaScript が URL でフレームにアクセスしようとする を参照) 。

私の質問: データをバリデーターに送信して、ユーザーが自分のマークアップをチェックできるようにする方法はありますか?

4

1 に答える 1

1

以下のコード スニペットは、あなたが求めているのと同じ効果とユーザー エクスペリエンスを得ることができると思います。

$.ajax(…)これは、いくつかの jQuery を使用して記述されてDOMParserおりdocument.write(…)、W3C HTML チェッカーのスタイル設定された結果と UI を新しいウィンドウに希望どおりに表示します。

var validator_baseurl= "https://validator.w3.org/nu/";
var validator_requesturl = validator_baseurl
    + "?showsource=yes&showoutline=yes";
$.ajax({
    url: validator_requesturl,
    type: "POST",
    crossDomain: true,
    data: storyhtml,
    contentType: "text/html;charset=utf-8",
    dataType: "html",
    success: function (response) {
        var results = (new DOMParser()).parseFromString(response, "text/html");
        results.querySelector("link[rel=stylesheet]").href
            = validator_baseurl + "style.css";
        results.querySelector("script").src
            = validator_baseurl + "script.js";
        results.querySelector("form").action
            = validator_requesturl;
        var newWin = window.open("about:blank",
            "Checker results", "height=825,width=700");
        newWin.document.open();
        newWin.document.write(results.documentElement.outerHTML);
        newWin.document.close();
        newWin.location.hash = "#textarea";
        setTimeout(function() {
            newWin.document.querySelector("textarea").rows = "5";
        }, 1000)
    }
});

説明

  • POST リクエストをW3C HTML チェッカーに送信する
  • storyhtmlテキストを POST 本文にする
  • text/html;charset=utf-8POST 本文のメディア タイプを作成します (チェッカーが期待するもの)
  • チェッカーが実際にstoryhtmlコンテンツを自動的にチェックするようにします
  • チェッカーの結果を最初に開いたときに新しいウィンドウに 1 つのステップで表示します (そのため、ユーザーは自分自身をチェックするために手動で送信するために 2 番目のステップを実行する必要はありません)。
  • チェッカーのフロントエンド CSS+JS の相対 URL を絶対 URL に置き換えます (そうしないと、この「スタンドアロン ウィンドウ」コンテキストでは、CSS が適用されず、スクリプトが実行されません)。
  • newWin.location.hash = "#textarea"チェッカーにテキストエリアを表示させるために必要です

ノート

  • 現在のW3C HTML チェッカーを意図的に使用します(従来の W3C マークアップ検証ツールではありません)。

  • チェックするコンテンツを ) ではなく、意図的に POST 本文として送信しますmultipart/form-data。チェッカーはサポートしていますmultipart/form-dataが、POST 本体にする方が簡単で優れています

  • setTimeout textareaビットは必要ありません。スクロールせずに結果が表示されるようにするだけです(テキストエリアの下の新しいウィンドウの下部)。もちろん、必要に応じて削除できます

  • 新しいウィンドウの高さと幅を、質問の元のコードの 600x600 より少し大きく設定します。繰り返しますが、見やすくするためにそうしました。好きなように変更してください

  • より優れたjQueryメソッド/イディオムを持つ可能性のある標準DOM操作を使用します(私は通常jQueryを使用しないので、JQueryの周りでコードをさらに合理化する方法があると想像できます)

  • もちろん、jQuery をまったく使用せずに、代わりに標準のFetchまたは XHR を使用して実行することもできます (必要に応じて、Fetch と XHR を使用する例もここに追加できれば幸いです)。

  • テスト済みで、Edge、Firefox、Chrome、Safari で期待どおりに動作します。ただし、を使用するコードと同様document.openに、Safari ユーザーは[設定] > [セキュリティ] > [ポップアップ ウィンドウをブロック] の設定を解除する必要があります。

于 2015-09-13T09:12:44.990 に答える