Ну, я не знаю, является ли это самым изящным решением, но мне это удалось, указав, что 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
Я все еще работаю над всеми подробностями, когда дело доходит до определения условий соединения, но я надеюсь, что это поможет.
Вы должны использовать eval () для выполнения любого кода скрипта, который вы вставили в виде текста DOM.
MooTools сделает это за вас автоматически, и я Конечно, jQuery также будет (в зависимости от версии. jQuery версии 1.6+ использует eval
). Это экономит много хлопот по разборке <script>
тегов и экранированию вашего контента, а также кучу других «ошибок».
Как правило, если вы собираетесь eval()
сами, вы хотите создать / отправить код сценария без какой-либо разметки HTML, такой как <script>
, поскольку они не будут eval()
правильно.
Вот рекурсивная функция для установки 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);
}
}
Вы можете увидеть демо здесь .
Тег 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());
});`
В моем блоге вы можете узнать больше здесь .
Используйте $(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
})
}
Я использовал этот код, он отлично работает
var arr = MyDiv.getElementsByTagName('script')
for (var n = 0; n < arr.length; n++)
eval(arr[n].innerHTML)//run script inside div
Мое решение этой проблемы - установить 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});
Попробуйте использовать шаблон и 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>
Вы можете сделать это следующим образом:
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);
}
Для тех, кто все еще пытается это сделать, нет, вы не можете вставлять скрипт с помощью 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_
.
Вот метод, который рекурсивно заменяет все скрипты исполняемыми:
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]);
Да, вы можете, но вы должны сделать это за пределами 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;
}
Вы можете создать скрипт, а затем ввести содержимое.
var g = document.createElement('script');
var s = document.getElementsByTagName('script')[0];
g.text = "alert(\"hi\");"
s.parentNode.insertBefore(g, s);
Это работает во всех браузерах:)
document.documentElement
.
– Eli Grey
14 August 2011 в 09:01
<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
<script>
. Например. <img onerror="..." src="#">
и <body onload="...">
. Если вы хотите быть техничным, это не будет работать в документах, отличных от HTML / SVG, из-за неявного пространства имен.
– Eli Grey
15 August 2011 в 05:14
Красимир Цонев имеет отличное решение, которое преодолевает все проблемы. Его метод не требует использования eval, поэтому никаких проблем с производительностью и безопасностью не существует. Он позволяет вам установить строку innerHTML, содержащую html с js, и немедленно перевести его на элемент DOM, а также выполнить js-части, существующие вдоль кода. короткий, простой и работает точно так, как вы хотите.
Наслаждайтесь его решением:
http://krasimirtsonev.com/blog/article/Convert-HTML-string- to-DOM-элемент
Важные замечания:
Вот очень интересное решение вашей проблемы: http://24ways.org/2005/have-your-dom-and-script-it-too
Поэтому используйте это вместо тегов скрипта:
<img src="empty.gif" onload="alert('test');this.parentNode.removeChild(this);" />
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">
(это не будет делать сетевой запрос). Фактически ... вам НЕ нужно изображение, ссылка на несуществующее изображение и вместо onload
использовать onerror
(но это сделает сетевой запрос)
– Danny '365CSI' Engelman
20 October 2016 в 08:45
<script>
сinnerHTML
может быть коротким, но это не работает. Все это просто текст, пока он не пройдет черезeval()
. И, к сожалению,eval()
не анализирует HTML-теги, поэтому вы получаете целую цепочку проблем. – zombat 29 July 2009 в 02:46