2009-04-01 19 views
6

Cho phép giả sử rằng tôi có đánh dấu sau:Làm cách nào để chèn javascript vào một trang trên IE 8?

<div id="placeHolder"></div> 

và tôi có một biến JavaScript jsVar có chứa một số đánh dấu và một số JavaScript.

Bằng cách sử dụng Mootools 1.1 Tôi có thể tiêm nội dung Javascript vào giữ chỗ như thế này:

$('placeHolder').setHTML(jsVar); 

này hoạt động trong Firefox, Opera, và thậm chí cả Safari và đánh dấu kết quả trông như thế này:

<div id="placeHolder"> 
    <strong>I was injected</strong> 
    <script type="text/javascript"> 
     alert("I was injected too!"); 
    </script> 
</div> 

Tuy nhiên, trên IE 8 tôi nhận được như sau:

<div id="placeHolder"> 
    <strong>I was injected</strong> 
</div> 

có cách để tiêm JavaScript trên IE 8 hoặc mô hình bảo mật có cấm tôi làm điều này không?

Tôi cố gắng gợi ý của việc sử dụng

document.getElementById("placeHolder").innerHTML = jsVar; 

thay vì mã MooTools Luca Matteis' và tôi nhận được kết quả tương tự. Đây không phải là vấn đề về MooTools.

Trả lời

1

Tôi không chắc chắn về MooTools, nhưng bạn đã thử innerHTML chưa?

document.getElementById ("placeHolder"). InnerHTML = jsVar;

+0

Tôi vừa thử nó. Tôi nhận được kết quả tương tự. Nhưng cảm ơn, điều này chứng minh rằng nó không phải là một vấn đề mootools. – adolfojp

1

Bạn có thể cần phải đánh giá nội dung của thẻ tập lệnh. Điều này sẽ yêu cầu phân tích cú pháp để tìm các tập lệnh trong jsVar của bạn và eval (whatsBetweenTheScriptTags).

+0

Đó là con đường mà tôi sẽ phải tuân theo. Tôi hiện đang sử dụng eval, hoặc thực hiện một chức năng tạm thời trên nội dung của các phần tử script trong phần tử giữ chỗ chính. Bởi vì IE 8 không chèn các kịch bản vào đánh dấu, tôi sẽ phải phân tích cú pháp chúng ở cấp độ biến. Nó hoạt động. – adolfojp

5

MSDN post đặc biệt giải quyết cách sử dụng innerHTML để chèn javascript vào trang. Bạn nói đúng: IE coi đây là vấn đề bảo mật, vì vậy yêu cầu bạn phải nhảy qua các vòng nhất định để lấy tập lệnh được tiêm ... có lẽ tin tặc có thể đọc bài đăng MSDN này cũng như chúng tôi có thể, vì vậy tôi thua lỗ lý do tại sao MS xem xét thêm lớp indirection "an toàn", nhưng tôi digress.

Từ bài viết MSDN:

<HTML> 
<SCRIPT> 
function insertScript(){ 
    var sHTML="<input type=button onclick=" + "go2()" + " value='Click Me'><BR>"; 
    var sScript="<SCRIPT DEFER>"; 
    sScript = sScript + "function go2(){ alert('Hello from inserted script.') }"; 
    sScript = sScript + "</SCRIPT" + ">"; 
    ScriptDiv.innerHTML = sHTML + sScript; 
}  
</SCRIPT> 
<BODY onload="insertScript();"> 
    <DIV ID="ScriptDiv"></DIV> 
</BODY> 
</HTML> 

Nếu có thể, bạn có thể muốn xem xét sử dụng một document.write tiêm thẻ script tải để tăng cường an ninh và giảm không tương thích qua trình duyệt. Tôi hiểu điều này có thể không thực hiện được, nhưng đáng xem xét.

+1

http://forums.microsoft.com/msdn/showpost.aspx?postid=909379&siteid=1 Tập lệnh trong IE là phần tử NoScope. Và các phần tử NoScope được xóa khỏi phần đầu của HTML được phân tích cú pháp trước khi nó được chèn với innerHTML hoặc insertAdjacentHTML. Nó âm thanh không được coi là một vấn đề an ninh. –

1

Vì IE từ chối chèn nội dung theo mặc định, bạn sẽ phải thực thi nó, nhưng bạn ít nhất có thể lừa IE thực hiện phân tích cú pháp cho bạn.

Chỉ cần sử dụng string.replace() để hoán đổi tất cả các thẻ <script> cho <textarea class="myScript" style="display:none">, giữ nguyên nội dung. Sau đó, dán kết quả vào một innerHTML của một div.

Sau này được thực hiện, bạn có thể sử dụng

div.getElementsByTagName("textarea") 

để có được tất cả các textareas, vòng qua chúng và tìm kiếm lớp đánh dấu của bạn ("myScript" trong trường hợp này), và một trong hai eval(textarea.value) hoặc (new Function(textarea.value))() những người bạn quan tâm trong khoảng.

1

Tôi chưa bao giờ thử nó, nó chỉ đến để tâm trí của tôi ... Bạn có thể thử như sau:

var script = document.createElement('script'); 
script.type = 'text/javascript'; 

script.innerHTML = '//javascript code here'; // not sure if it works 
// OR 
script.innerText = '//javascript code here'; // not sure if it works 
// OR 
script.src = 'my_javascript_file.js'; 

document.getElementById('placeholder').appendChild(script); 

Bạn có thể sử dụng kỹ thuật tương tự (DOM) để chèn mã HTML.

4

Đây là cách chúng tôi đã thực hiện trên trang web của chúng tôi khoảng một năm trước để làm cho nó hoạt động trong IE. Dưới đây là các bước:

  • thêm HTML để một đứa trẻ mồ côi phần tử DOM
  • tìm nút đứa trẻ mồ côi cho thẻ script (orphan.getElementsByTagName)
  • lấy mã từ những nút kịch bản (tiết kiệm cho sau này), và sau đó xóa chúng khỏi trẻ mồ côi
  • thêm html còn sót lại vào trong trại trẻ mồ côi và thêm nó vào trình giữ chỗ (placeholder.innerHTML = orphan.innerHTML)
  • tạo phần tử tập lệnh và thêm mã được lưu vào đó (scriptElem .text = 'alert ("mã của tôi");')
  • sau đó thêm các yếu tố kịch bản vào DOM (tốt nhất là người đứng đầu), sau đó loại bỏ nó
 
function set_html(id, html) { 
    // create orphan element set HTML to 
    var orphNode = document.createElement('div'); 
    orphNode.innerHTML = html; 

    // get the script nodes, add them into an arrary, and remove them from orphan node 
    var scriptNodes = orphNode.getElementsByTagName('script'); 
    var scripts = []; 
    while(scriptNodes.length) { 
     // push into script array 
     var node = scriptNodes[0]; 
     scripts.push(node.text); 

     // then remove it 
     node.parentNode.removeChild(node); 
    } 

    // add html to place holder element (note: we are adding the html before we execute the scripts) 
    document.getElementById(id).innerHTML = orphNode.innerHTML; 

    // execute stored scripts 
    var head = document.getElementsByTagName('head')[0]; 
    while(scripts.length) { 
     // create script node 
     var scriptNode = document.createElement('script'); 
     scriptNode.type = 'text/javascript'; 
     scriptNode.text = scripts.shift(); // add the code to the script node 
     head.appendChild(scriptNode); // add it to the page 
     head.removeChild(scriptNode); // then remove it 
    } 
} 

set_html('ph', 'this is my html. alert("alert");'); 
0

Khi bạn nói nó là "tác phẩm" trong những trình duyệt khác, bạn có nghĩa là bạn nhận được thông báo alert popup, hoặc bạn chỉ có nghĩa là thẻ <script> biến nó thành cây DOM?

Nếu mục tiêu của bạn là trước đây, hãy nhận ra rằng hành vi tiêm html với nhúng <script> phụ thuộc rất nhiều vào trình duyệt. Ví dụ trong MooTools mới nhất tôi có thể thử:

$(element).set('html', '<strong>Foo</strong><script>alert(3)</script>') 

và tôi làm không được popup, không phải trong IE (7), không phải trong FF (3) (tuy nhiên tôi làm được nút <script> vào DOM thành công). Để truy cập vào alert trong tất cả các trình duyệt, bạn phải làm như this answer.

1

Tôi xin lỗi, có lẽ tôi đang thiếu điều gì đó ở đây - nhưng với điều này là một câu hỏi về mootools 1.11, tại sao bạn không sử dụng assets.js?

// you can also add a json argument with events, etc. 
new Asset.javascript("path-to-script.js", { 
    onload: function() { 
     callFuncFromScript(); 
    }, 
    id: "myscript" 
}); 

Không phải là một trong những lý do tại sao chúng tôi đang sử dụng một khuôn khổ không phải phát minh lại bánh xe khắp nơi trên một lần nữa ...

như xa như nội dung 'khác' là có liên quan , làm thế nào để bạn có thể nhận được nó?nếu thông qua các lớp yêu cầu, nó có thể làm những gì bạn muốn độc đáo bằng cách sử dụng các tùy chọn:

{ 
    update: $("targetId"), 
    evalScripts: true, 
    evalResponse: false 
} 
2

tôi đã gặp phải những vấn đề tương tự với IE8 (và IE7) Cách duy nhất tôi tự động có thể tiêm một kịch bản (với một src) là bằng cách sử dụng một bộ đếm thời gian:

source = "bla.js"; 

setTimeout(function() { 
      // run main code 
      var s = document.createElement('script'); 
      s.setAttribute('src', source); 
      document.getElementsByTagName('body')[0].appendChild(s); 
     }, 50); 

Nếu bạn có mã inline bạn muốn tiêm, bạn có thể thả bộ đếm thời gian và sử dụng phương pháp "văn bản" cho các phần tử kịch bản:

s.text = "alert('hello world');"; 

Tôi biết câu trả lời của tôi đã đến khá muộn; Tuy nhiên, tốt hơn muộn hơn không bao giờ :-)

0

Và bình luận của tôi thực sự là muộn, nhưng nó cũng chính xác nhất ở đây - lý do bạn không nhìn thấy nội dung <script> đang chạy là vì bạn không thêm thuộc tính defer vào thẻ <script>. Bài viết MSDN cụ thể nói rằng bạn cần phải làm điều đó để thẻ <script> chạy.

Các vấn đề liên quan