13

サイト所有者がhttp://example.com<script src="http://ours.com/some.js"></script>のようにサイトに配置するなどの JavaScript タグの一部を提供します。この JavaScript タグには、document.write を含めることができるサードパーティの js などを動的に含めたいと考えています。ですが、もちろん従来の方法で入れようとすると、

var script_tag = document.createElement('script');
script_tag.type = 'text/javascript';
script_tag.src="http://third-party.com/some.js";
document.getElementById('target').appendChild(script_tag);

ブラウザから警告が表示され、

警告: 非同期にロードされた外部スクリプトからの document.write() の呼び出しは無視されました。

どうすればこれを回避できますか? サードパーティのスクリプトを実際に制御できないため、そのロジックを変更できないことに注意してください。すべてのブラウザで機能するソリューションを探しています。

4

7 に答える 7

1

次のように document.write の呼び出しをインターセプトすることで、スクリプト インジェクションを正しい方法でサポートできます。

document.writeText = document.write;

document.write = function(parameter) {
    if (!parameter) return; 
    var scriptPattern = /<script.*?src=['|"](.*?)['|"]/;
    if (scriptPattern.test(parameter)) {
        var srcAttribute = scriptPattern.exec(parameter)[1];
        var script = document.createElement('script');
        script.src = srcAttribute;
        document.head.appendChild(script); 
    }
    else {
        document.writeText(parameter);
    }   
};

明らかに、これはもう少し圧縮できますが、わかりやすくするために変数名が含まれています。

ソース

于 2017-01-18T11:11:10.557 に答える
0

Another procedure is to change the behavior of document.write() function.
Assume you have the main index.php file:

<html>
<head>
<meta charset="utf-8" />
</head>
<body>
Hello<br>
<div id="target"></div>
<script>
document.write = function(input) {
    document.body.innerHTML += input;
}
var doit = function() {
    var script_tag = document.createElement('script');
    script_tag.type = 'text/javascript';
    script_tag.src="http://127.0.0.1:8080/testPlace/jsfile.js";
    document.getElementById('target').appendChild(script_tag);
}
</script>
</body>
</html>

and the jsfile.js is like this:

document.write("OK MAN!");

now if you type doit() in the js browser console to execute that function (and the script do what you wrote) then the result would be:

Hello
OK MAN!

In which the html is like this:

<html><head>
<meta charset="utf-8">
</head>
<body>
Hello<br>
<div id="target"><script src="http://127.0.0.1:8080/testPlace/jsfile.js" type="text/javascript"></script></div>
<script>
    //That Script which here I removed it to take less space in answer
</script>

OK MAN!</body>
</html>
于 2015-09-07T18:38:34.073 に答える
0

Document.write は、スクリプトの動作開始時にドキュメントが既に読み込まれているため、非同期スクリプトからは動作しません。

しかし、これを行うことができます:

document.body.innerHTML = document.body.innerHTML + '<h1>Some HTML</h1>';

于 2015-09-07T13:00:49.253 に答える
0

script 要素を追加してスクリプトをロードする代わりに、スクリプト URL のコンテンツを AJAX 呼び出しでロードし、eval() を使用してグローバル スコープで実行するのはどうでしょうか。ここに例を示します。動作することを確認するためにテストしました。

<!DOCTYPE html>
<html>
<head>
<script>

var xmlhttp;

if (window.XMLHttpRequest) {
  xmlhttp = new XMLHttpRequest();
}else{
  xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}

xmlhttp.onreadystatechange = function() {
  if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
    window.eval(xmlhttp.responseText); //Indirect call to eval to execute in global scope (http://perfectionkills.com/global-eval-what-are-the-options/)
  }
}

xmlhttp.open("GET", "https://third-party.com/test.js", false); //This is synchronous so that any document.write calls don't overwrite the entire page when they get called after the document is finished rendering. For all intents and purposes, this just loads the script like any other script, synchronously.

xmlhttp.send();

</script>
</head>
<body>

<div><h2>Hello World</h2></div>

</body>
</html>

test.js ファイルの内容は次のとおりです。

document.write("This is a test...");
alert("...This is a test alert...");
console.log("...And a console message.");

スクリプトの AJAX リクエストを同期化して、通常の埋め込みスクリプト タグとまったく同じように読み込まれるようにしました。非同期で実行し、ページが完全にレンダリングされた後にスクリプトが document.write を使用すると、DOM がクリアされてから書き込みが行われます...実際には面倒です。これがうまくいくかどうかを教えてください。:)

于 2015-09-02T09:21:33.900 に答える
-1

サードパーティの JavaScript ファイルとは何ですか?

Google Maps JavaScript API v3 の場合は、スクリプト URL に「&callback=your_init_funct」が含まれていることを確認してください。次に、マップ ライブラリが読み込まれると、'your_init_funct' が呼び出され、マップの表示を開始できるようになります。

別の解決策は、http: //bezen.org/javascript/index.htmlで入手できる bezen.domwrite.js です。

デモ: http://bezen.org/javascript/test/test-domwrite.html

于 2015-08-31T19:53:09.210 に答える