【问题标题】:JavaScript Document.Write Replaces All Body Content When Using AJAXJavaScript Document.Write 在使用 AJAX 时替换所有正文内容
【发布时间】:2010-03-02 00:07:14
【问题描述】:

我正在创建一个简单的 ajax 调用,它检索指定 url 的内容并将其写入页面。我遇到的问题是它用这些信息替换了整个正文内容

这里是 JS:

(function(){
    var mb = window.mb = {};

    function get_ad(url, parameters){
        var result = "";
        var http_request = false;

        if (window.XMLHttpRequest) { // Mozilla, Safari,...
            http_request = new XMLHttpRequest();
            if (http_request.overrideMimeType) {
                http_request.overrideMimeType('text/html');
            }
        } else if (window.ActiveXObject) { // IE
            var avers = ["Microsoft.XmlHttp", "MSXML2.XmlHttp", "MSXML2.XmlHttp.3.0", "MSXML2.XmlHttp.4.0", "MSXML2.XmlHttp.5.0"];
            for (var i = avers.length -1; i >= 0; i--) {
                try {
                    http_request = new ActiveXObject(avers[i]);
                    if (http_request){
                        break;  
                    }
                } catch(e) {}
            }
        }
        if (!http_request) {
            alert('Cannot create XMLHTTP instance');
            return false;
        }

        http_request.onreadystatechange = function(){
                                              if (http_request.readyState == 4) {
                                                 if (http_request.status == 200) {
                                                    gen_output(http_request.responseText);
                                                 } else {
                                                    alert('Error');
                                                 }
                                              }
                                           }

        http_request.open('GET', url + parameters, true);
        http_request.send(null);
    }

    function gen_output(ad_content){
        document.write("<div id=\"mb_ad\">");
        document.write(ad_content);
        document.write("</div>");
    }

    get_ad("http://localhost/test/test.html", "");
})();

这里是html:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>

<body>
    i am text before <br/>
    <script type="text/javascript" src="mb.js"></script>
    <br />
    i am text after 
</body>
</html>

使用 firebug 进行检查,我没有看到之前或之后的文本,只有 &lt;div id="mb_ad"&gt; 和 test.html 页面中的内容。如果我删除 ajax 调用并只执行 3 document.writes 之前的文本,之后的文本将正确显示。 jQuery 不是一个选项,我必须在没有大型库的帮助的情况下这样做,因为大小和速度至关重要。

【问题讨论】:

  • 我找不到您的代码可能有什么问题,我想它需要更多检查/断点。但是对于“jQuery 不是一个选项”,我真的不同意,24ko 的 javascript(如果使用 google CDN 可能会被缓存)在网页上确实没有什么不同。如果您有如此强烈的要求,我不确定网站甚至网络应用程序是否是个好主意。
  • 此外,您可以使用轻量级库,例如 DOMAssistant 或类似的。
  • 这与该脚本将被插入到其他网站这一事实有关,因此将像 jquery 这样的库添加到可能正在使用其他库的网站,甚至可能是 jquery 本身,只会造成问题。
  • @downvoter 想评论一下你为什么对一个 5 年前的问题投了反对票?

标签: javascript ajax


【解决方案1】:

文档加载完成后,您将无法使用document.write。如果这样做,浏览器将打开一个替换当前文档的新文档。

使用 innerHTML 属性将 HTML 代码放入元素中:

function gen_output(ad_content){
  document.getElementById('mb_ad').innerHTML = ad_content;
}

将元素放在脚本之前,这样在调用回调函数的时候就可以确定它存在:

i am text before
<div id="mb_ad"></div>
i am text after
<script type="text/javascript" src="mb.js"></script>

将脚本放在哪里并不重要,因为不会将任何内容写入它所在的文档。

【讨论】:

  • 如果没有单独的div,是否有可能完成我正在尝试的事情?这应该是嵌入到客户站点中的东西,我被要求通过单个脚本调用来完成。
  • 是的,您可以在进行 AJAX 调用之前使用 document.write 将 div 写入页面。
【解决方案2】:

如果您无法控制远程脚本,您可以编写如下内容:

<script>
var tmp = document.write;

document.write = function () {
  document.getElementById('someId').innerHTML = [].concat.apply([], arguments).join('');
};
</script>
<script .....>
document.write = tmp;

嗯,这是一个令人讨厌的黑客,但它似乎工作......

【讨论】:

    【解决方案3】:
    var div = document.createElement('div');
    div.id = 'mb_ad';
    div.innerHTML = ad_content;

    现在,您可以将此节点附加到任何您想要的位置。

    【讨论】:

      【解决方案4】:

      你可以使用&lt;script&gt;document.body.innerHTML+="//Your HTML Code Here";&lt;/script&gt;

      【讨论】:

        【解决方案5】:

        同样的 Leon Fedotov 答案,但更多的 jQuery

        {
          var old_write = document.write;
        
          var $zone = $('.zone.zone_' + name);
          // redefine document.write in this closure
          document.write = function () {
            $zone.append([].concat.apply([], arguments).join(''));
          };
          // OA_output[name] contains dangerous document.write
          $zone.html(OA_output[name]);
        
          document.write = old_write;
        }
        

        【讨论】:

          【解决方案6】:

          下面的代码我也遇到了同样的问题:

          $html[] = '<script>
                     if($("#mf_dialogs").length == 0) {
                         document.write("<div id=\"mf_dialogs\"></div>");
                     }
                     </script>';
          

          以下代码有效地替换了 document.write:

          $html = '<div id="dialogHolder"></div>
                   <script>
                        if($("#mf_dialogs").length == 0) {
                            document.getElementById("dialogHolder").innerHTML="<div id=\"mf_dialogs\"></div>";
                        }
                   </script>';
          

          【讨论】:

            【解决方案7】:

            您可以在某种程度上模拟document.write 的方式是以下代码:

            <script>
              (function(script) {
                var parent = script.parentNode;
                var node = document.createTextNode('Surprise!');
                parent.replaceChild(node, script);
              })(document.currentScript);
            </script>
            

            通过这种方式,您可以将任意 HTML 替换为 script 元素。如果你有一个更简单的情况,比如你可以将脚本包装在另一个标签中,你可以做更简单的版本。

            <script>
              document.currentScript.parentElement.innerHTML = 'Surprise!';
            </script>
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2019-01-06
              • 1970-01-01
              • 2021-10-04
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多