XMLHttpRequest Не загружать путь к файлу jquery [дубликат]

Ну, я не знаю, является ли это самым изящным решением, но мне это удалось, указав, что self.table_name_prefix явно возвращает имя базы данных.

class Visit < ActiveRecord::Base
  def self.table_name_prefix
    renv = ENV['RAILS_ENV'] || ENV['RACK_ENV']
    (renv.empty? ? "lab." : "lab_#{renv}.")
  end

  self.establish_connection "lab"
  belongs_to :patient
end

class Patient < ActiveRecord::Base
  def self.table_name_prefix
    renv = ENV['RAILS_ENV'] || ENV['RACK_ENV']
    (renv.empty? ? "main." : "main_#{renv}.")
  end

  self.establish_connection "main"
  has_many :visits
end

Я все еще работаю над всеми подробностями, когда дело доходит до определения условий соединения, но я надеюсь, что это поможет.

169
задан Mosh Feu 24 December 2015 в 10:29
поделиться

15 ответов

Вы должны использовать eval () для выполнения любого кода скрипта, который вы вставили в виде текста DOM.

MooTools сделает это за вас автоматически, и я Конечно, jQuery также будет (в зависимости от версии. jQuery версии 1.6+ использует eval). Это экономит много хлопот по разборке <script> тегов и экранированию вашего контента, а также кучу других «ошибок».

Как правило, если вы собираетесь eval() сами, вы хотите создать / отправить код сценария без какой-либо разметки HTML, такой как <script>, поскольку они не будут eval() правильно.

70
ответ дан Travis J 15 August 2018 в 20:29
поделиться
  • 1
    То, что я действительно хочу сделать, - загрузить внешний скрипт, а не просто использовать некоторый локальный скрипт. Добавление тега script с помощью innerHTML намного короче, чем создание элемента DOM скрипта и добавление его в тело, и я пытаюсь сделать мой код как можно короче. Вам нужно создать элементы dom dom и добавить их в dom, а не просто использовать что-то вроде innerHTML? Есть ли способ сделать это с помощью document.write изнутри функции? – Craig 29 July 2009 в 02:23
  • 2
    Как следует из zombat, используйте фреймворк Javascript для загрузки внешнего скрипта, не пытайтесь изобретать колесо. JQuery делает это очень просто, просто включите JQuery и вызовите: $ .getScript (url). Вы также можете предоставить функцию обратного вызова, которая будет выполняться после загрузки сценария. – Ariel Popovsky 29 July 2009 в 02:33
  • 3
    Ариэль прав. Я очень хочу, чтобы ваш код был коротким, а добавление тега <script> с innerHTML может быть коротким, но это не работает. Все это просто текст, пока он не пройдет через eval(). И, к сожалению, eval() не анализирует HTML-теги, поэтому вы получаете целую цепочку проблем. – zombat 29 July 2009 в 02:46
  • 4
    eval () не является отличным решением любой проблемы. – buley 13 October 2011 в 16:47
  • 5
    Я попробовал eval () сам. Это ужасная идея. Вы должны оценить все КАЖДОЕ ВРЕМЯ . Даже если вы объявляете имя переменной и значение, вы должны повторно объявлять / повторно-eval () каждый раз заново, чтобы заставить ее работать. Это кошмар ошибок. – Youstay Igo 4 November 2015 в 13:17

Вот рекурсивная функция для установки innerHTML элемента, который я использую на нашем сервере объявлений:

// o: container to set the innerHTML
// html: html text to set.
// clear: if true, the container is cleared first (children removed)
function setHTML(o, html, clear) {
    if (clear) o.innerHTML = "";

    // Generate a parseable object with the html:
    var dv = document.createElement("div");
    dv.innerHTML = html;

    // Handle edge case where innerHTML contains no tags, just text:
    if (dv.children.length===0){ o.innerHTML = html; return; }

    for (var i = 0; i < dv.children.length; i++) {
        var c = dv.children[i];

        // n: new node with the same type as c
        var n = document.createElement(c.nodeName);

        // copy all attributes from c to n
        for (var j = 0; j < c.attributes.length; j++)
            n.setAttribute(c.attributes[j].nodeName, c.attributes[j].nodeValue);

        // If current node is a leaf, just copy the appropriate property (text or innerHTML)
        if (c.children.length == 0)
        {
            switch (c.nodeName)
            {
                case "SCRIPT":
                    if (c.text) n.text = c.text;
                    break;
                default:
                    if (c.innerHTML) n.innerHTML = c.innerHTML;
                    break;
            }
        }
        // If current node has sub nodes, call itself recursively:
        else setHTML(n, c.innerHTML, false);
        o.appendChild(n);
    }
}

Вы можете увидеть демо здесь .

0
ответ дан Adnan Korkmaz 15 August 2018 в 20:29
поделиться

Тег Execute (Java Script) из innerHTML

Замените ваш скриптовый элемент div, имеющим класс class class = "javascript", и закройте его с помощью </div>

Не выполняйте измените контент, который вы хотите выполнить (ранее он был в теге скрипта, и теперь он находится в теге div)

Добавьте стиль на свою страницу ...

<style type="text/css"> .javascript { display: none; } </style>

Теперь запустите eval с помощью jquery (JQuery js должен быть уже включен)

   $('.javascript').each(function() {
      eval($(this).text());

    });`

В моем блоге вы можете узнать больше здесь .

-1
ответ дан Andrew Barber 15 August 2018 в 20:29
поделиться

Используйте $(parent).html(code) вместо parent.innerHTML = code.

Ниже также исправлены скрипты, использующие document.write и скрипты, загруженные через атрибут src. К сожалению, даже это не работает с скриптами Google AdSense.

var oldDocumentWrite = document.write;
var oldDocumentWriteln = document.writeln;
try {
    document.write = function(code) {
        $(parent).append(code);
    }
    document.writeln = function(code) {
        document.write(code + "<br/>");
    }
    $(parent).html(html); 
} finally {
    $(window).load(function() {
        document.write = oldDocumentWrite
        document.writeln = oldDocumentWriteln
    })
}

Источник

1
ответ дан Community 15 August 2018 в 20:29
поделиться
  • 1
    немного поздно, но каждый, кто может использовать этот метод, заметил, что в JQuery вам нужно загрузить свои скрипты, используя $ .loadScript (url), а не & lt; script src = & quot; url & gt; & lt; / script & gt; - последний приведет к устаревшей синхронной ошибке XMLHttpRequest в браузерах. – Stavm 23 November 2016 в 14:57

Я использовал этот код, он отлично работает

var arr = MyDiv.getElementsByTagName('script')
for (var n = 0; n < arr.length; n++)
    eval(arr[n].innerHTML)//run script inside div
25
ответ дан Firas Nizam 15 August 2018 в 20:29
поделиться
  • 1
    Благодарю. У меня была проблема с добавлением универсального кода Disqus в модальное всплывающее окно, созданное с помощью плагина TinyBox2 JQuery. – gsinha 6 July 2014 в 02:32
  • 2
    К сожалению, это решение не работает, когда скрипт содержит функции, которые будут вызываться позже. – Jose Gómez 16 July 2015 в 01:16
  • 3
    это также не работает для внешних скриптов – programmer5000 2 May 2018 в 19:20

Мое решение этой проблемы - установить Mutation Observer для обнаружения узлов <script></script>, а затем заменить его новым узлом <script></script> с тем же src. Например:

let parentNode = /* your node */ void 0
let observer = new MutationObserver(mutations=>{
    mutations.map(mutation=>{
        Array.from(mutation.addedNodes).map(node=>{
            if ( node.parentNode == parentNode ) {
                let scripts = node.getElementsByTagName('script')
                Array.from(scripts).map(script=>{
                    let src = script.src
                    script = document.createElement('script')
                    script.src = src
                    return script
                })
            }
        })
    })
})
observer.observe(document.body, {childList: true, subtree: true});
-2
ответ дан gabriel garcia 15 August 2018 в 20:29
поделиться

Попробуйте использовать шаблон и document.importNode. Вот пример:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Sample</title>
</head>
<body>
<h1 id="hello_world">Sample</h1>
<script type="text/javascript">
 var div = document.createElement("div");
  var t = document.createElement('template');
  t.innerHTML =  "Check Console tab for javascript output: Hello world!!!<br/><script type='text/javascript' >console.log('Hello world!!!');<\/script>";
  
  for (var i=0; i < t.content.childNodes.length; i++){
    var node = document.importNode(t.content.childNodes[i], true);
    div.appendChild(node);
  }
 document.body.appendChild(div);
</script>
 
</body>
</html>

1
ответ дан Gray 15 August 2018 в 20:29
поделиться
  • 1
    Это не работает с Microsoft Edge, любым другим способом? – Soul 23 March 2018 в 01:24

Вы можете сделать это следующим образом:

var mydiv = document.getElementById("mydiv");
var content = "<script>alert(\"hi\");<\/script>";

mydiv.innerHTML = content;
var scripts = mydiv.getElementsByTagName("script");
for (var i = 0; i < scripts.length; i++) {
    eval(scripts[i].innerText);
}
0
ответ дан Jake 15 August 2018 в 20:29
поделиться

Для тех, кто все еще пытается это сделать, нет, вы не можете вставлять скрипт с помощью innerHTML, но можно загрузить строку в тег скрипта с помощью Blob и URL.createObjectURL.

Я создал пример, который позволяет запускать строку как скрипт и получать «экспорт» скрипта, возвращенного с помощью обещания:

function loadScript(scriptContent, moduleId) {
    // create the script tag
    var scriptElement = document.createElement('SCRIPT');

    // create a promise which will resolve to the script's 'exports'
    // (i.e., the value returned by the script)
    var promise = new Promise(function(resolve) {
        scriptElement.onload = function() {
            var exports = window["__loadScript_exports_" + moduleId];
            delete window["__loadScript_exports_" + moduleId];
            resolve(exports);
        }
    });

    // wrap the script contents to expose exports through a special property
    // the promise will access the exports this way
    var wrappedScriptContent =
        "(function() { window['__loadScript_exports_" + moduleId + "'] = " + 
        scriptContent + "})()";

    // create a blob from the wrapped script content
    var scriptBlob = new Blob([wrappedScriptContent], {type: 'text/javascript'});

    // set the id attribute
    scriptElement.id = "__loadScript_module_" + moduleId;

    // set the src attribute to the blob's object url 
    // (this is the part that makes it work)
    scriptElement.src = URL.createObjectURL(scriptBlob);

    // append the script element
    document.body.appendChild(scriptElement);

    // return the promise, which will resolve to the script's exports
    return promise;
}

...

function doTheThing() {
    // no evals
    loadScript('5 + 5').then(function(exports) {
         // should log 10
        console.log(exports)
    });
}

Я упростил это из своего фактическая реализация, поэтому нет обещаний о том, что в нем нет ошибок. Но принцип работает.

Если вам не нужно возвращать какое-либо значение после запуска скрипта, это еще проще; просто оставьте Promise и onload бит. Вам даже не нужно обернуть скрипт или создать глобальное свойство window.__load_script_exports_.

4
ответ дан JayArby 15 August 2018 в 20:29
поделиться
  • 1
    Я просто попробовал, и он работает на chrome 57. innerHTML на теге скрипта выполняет текст. – iPherian 22 April 2017 в 06:35
  • 2
    Это интересно, раньше это не сработало. Интересно, является ли это поведение кросс-браузером или только в chrome 57. – JayArby 2 May 2017 в 21:51

Вот метод, который рекурсивно заменяет все скрипты исполняемыми:

function nodeScriptReplace(node) {
        if ( nodeScriptIs(node) === true ) {
                node.parentNode.replaceChild( nodeScriptClone(node) , node );
        }
        else {
                var i        = 0;
                var children = node.childNodes;
                while ( i < children.length ) {
                        nodeScriptReplace( children[i++] );
                }
        }

        return node;
}
function nodeScriptIs(node) {
        return node.tagName === 'SCRIPT';
}
function nodeScriptClone(node){
        var script  = document.createElement("script");
        script.text = node.innerHTML;
        for( var i = node.attributes.length-1; i >= 0; i-- ) {
                script.setAttribute( node.attributes[i].name, node.attributes[i].value );
        }
        return script;
}

Пример вызова:

nodeScriptReplace(document.getElementsByTagName("body")[0]);
54
ответ дан momo 15 August 2018 в 20:29
поделиться
  • 1
    Я немного удивлен, что ваш ответ все это вниз. ИМХО, это лучшее решение, этот метод позволит даже ограничить скрипты конкретными URL-адресами или контентом. – davidmh 2 April 2014 в 22:55
  • 2
    теперь работает в firefox – inf3rno 19 June 2015 в 08:53
  • 3
    @ inf3rno делает или нет? Он работал, никто никогда не утверждал ничего другого? – momo 19 June 2015 в 09:36
  • 4
    в чем цель [0]? вы можете использовать nondeScript Replace (document.getElementById (). html); – Bao Thai 21 April 2017 в 01:17
  • 5
    @BaoThai Да. Ты можешь. – momo 4 August 2017 в 22:03

Да, вы можете, но вы должны сделать это за пределами DOM, и порядок должен быть прав.

var scr = '<scr'+'ipt>alert("foo")</scr'+'ipt>';
window.onload = function(){
    var n = document.createElement("div");
    n.innerHTML = scr;
    document.body.appendChild(n);
}

... будет предупреждать «foo». Это не сработает:

document.getElementById("myDiv").innerHTML = scr;

И даже это не сработает, потому что узел сначала вставлен:

var scr = '<scr'+'ipt>alert("foo")</scr'+'ipt>';
window.onload = function(){
    var n = document.createElement("div");
    document.body.appendChild(n);
    n.innerHTML = scr;  
}
0
ответ дан mwilcox 15 August 2018 в 20:29
поделиться
  • 1
    Для чего это стоит: это, похоже, не работает в текущих браузерах. – Wichert Akkerman 31 January 2012 в 12:55
  • 2
    На самом деле это хорошая вещь. – jayarjo 4 October 2016 в 10:52

Вы можете создать скрипт, а затем ввести содержимое.

var g = document.createElement('script');
var s = document.getElementsByTagName('script')[0];
g.text = "alert(\"hi\");"
s.parentNode.insertBefore(g, s);

Это работает во всех браузерах:)

34
ответ дан Pablo Moretti 15 August 2018 в 20:29
поделиться
  • 1
    Если в документе нет других элементов сценария. Вместо этого используйте document.documentElement. – Eli Grey 14 August 2011 в 09:01
  • 2
    Не обязательно, потому что вы пишете скрипт из другого скрипта. <script> var g = document.createElement('script'); var s = document.getElementsByTagName('script')[0]; //reference this script g.text = "alert(\"hi\");" s.parentNode.insertBefore(g, s); </script> – Pablo Moretti 14 August 2011 в 10:11
  • 3
    Кто говорит, что это из другого сценария? Вы можете запускать JavaScript без элементов <script>. Например. <img onerror="..." src="#"> и <body onload="...">. Если вы хотите быть техничным, это не будет работать в документах, отличных от HTML / SVG, из-за неявного пространства имен. – Eli Grey 15 August 2011 в 05:14
  • 4
    Facebook использует ответ Пабло в своем SDK. developers.facebook.com/docs/javascript/quickstart/v2.2#loading – geoyws 8 February 2015 в 17:51

Красимир Цонев имеет отличное решение, которое преодолевает все проблемы. Его метод не требует использования eval, поэтому никаких проблем с производительностью и безопасностью не существует. Он позволяет вам установить строку innerHTML, содержащую html с js, и немедленно перевести его на элемент DOM, а также выполнить js-части, существующие вдоль кода. короткий, простой и работает точно так, как вы хотите.

Наслаждайтесь его решением:

http://krasimirtsonev.com/blog/article/Convert-HTML-string- to-DOM-элемент

Важные замечания:

  1. Вам нужно обернуть целевой элемент тегом div
  2. . Вам нужно обернуть строка src с тегом div.
  3. Если вы пишете строку src напрямую и включаете js-части, пожалуйста, обратите внимание на правильную запись тегов закрывающего скрипта (с \ before /), поскольку это строка.
1
ответ дан user3198805 15 August 2018 в 20:29
поделиться

Вот очень интересное решение вашей проблемы: http://24ways.org/2005/have-your-dom-and-script-it-too

Поэтому используйте это вместо тегов скрипта:

<img src="empty.gif" onload="alert('test');this.parentNode.removeChild(this);" />

70
ответ дан user447963 15 August 2018 в 20:29
поделиться
  • 1
    очень хороший и полностью работает во всех браузерах! – Jordi P.S. 25 September 2012 в 12:49
  • 2
    Это великолепно! – confile 20 August 2013 в 12:38
  • 3
    Не работает для меня, когда вставлен в результат запроса ajax: Ошибка синтаксиса; перед выражением в начале строки скрипта – Oliver 3 August 2014 в 03:30
  • 4
    Как вы добавляете строку & amp; lt; img src ... к вашему коду страницы? Вы document.write () или используете document.body.innerHTML + = подход для этого? Оба терпят неудачу для меня :( – Youstay Igo 4 November 2015 в 13:18
  • 5
    Вы можете Base64 кодировать ваше триггер-изображение как <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"> (это не будет делать сетевой запрос). Фактически ... вам НЕ нужно изображение, ссылка на несуществующее изображение и вместо onload использовать onerror (но это сделает сетевой запрос) – Danny '365CSI' Engelman 20 October 2016 в 08:45
0
ответ дан pixelherodev 29 October 2018 в 03:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: