He leído los otros temas de la misma política de origen aquí en SO, pero no he visto ninguna solución relacionada con el sistema de archivos local.
Tengo una aplicación web (en un sentido amplio de la palabra) que debe servirse localmente. Estoy tratando de cargar una gran cantidad de datos después de que el usuario haya cargado la página, dependiendo de lo que esté haciendo en la página web. En Firefox 3.5 e IE8 puedo usar los métodos AJAX() y GetScript() de jQuery para hacer esto, pero en Chrome esto falla debido a la política del mismo origen.
XMLHttpRequestno puede cargarfile://test/testdir/test.js.by Access-Control-Allow-Originorigennull.
Esto sucede cuando hago algo simple como
$.getScript("test.js");Esto funciona perfectamente bien en IE y Firefox.
Después de leer mucho sobre esto, decidí intentar escribir directamente en el encabezado del documento. En la consola en Chrome escribí lo siguiente:
var head = document.getElementsByTagName("head")[0]; var script =document.createElement('script'); script.id = 'uploadScript'; script.type = 'text/javascript'; script.src = "upload.js"; head.appendChild(script); Esto funciona bien cuando se pega en la consola: el elemento <script...test.js</script> se agrega al encabezado, se evalúa y el contenido se carga en el DOM.
Pensé que esto fue exitoso, hasta que puse este código en una llamada de función. El mismo código exacto, cuando se llama desde una función, agrega el elemento al archivo JavaScript pero no lo evalúa. No puedo entender por qué. Si uso la consola de Chrome para detener la ejecución en el método en el que agrega el elemento y ejecuto el código anterior, no lo evalúa. Sin embargo, si detengo la ejecución y ejecuto exactamente el mismo código (pegándolo en la ventana de la consola), funciona. No puedo explicar esto. ¿Alguien a lidiado con esto antes?
He leído las siguientes publicaciones de SO, pero no describen el problema que tengo:
Formas de eludir la política del mismo origen
XMLHttpRequest Origin null no está permitido Access-Control-Allow-Origin for file:/// to file:/// (Serverless)
XMLHttpRequest entre sitios
Una vez más, mi último recurso es cargar todos los datos en la carga de la página web. Esto puede causar un retraso de hasta 10 segundos en la carga de la página web que es innecesario para el 90 % de los usuarios de la aplicación.
Gracias por cualquier sugerencia/alternativas!!!
Creo que lo he descubierto.
Todo lo que realmente necesitaba hacer era agregar una devolución de llamada en mi etiqueta <script> . Código definitivo:
Tengo un elemento llamado next... Entonces, en la función $("#next").click() tengo el siguiente código. Esto solo se ejecuta si hacen clic en "siguiente".
//remove old dynamically written script tag- var old = document.getElementById('uploadScript'); if (old != null) { old.parentNode.removeChild(old); delete old; } var head = document.getElementsByTagName("head")[0]; script = document.createElement('script'); script.id = 'uploadScript'; script.type = 'text/javascript'; script.src = 'test/' + scope_dir + '/js/list.js'; script.onload = refresh_page; head.appendChild(script); function refresh_page(){ //perform action with data loaded from the .js file. }Esto parece funcionar y permite que Chrome cargue dinámicamente archivos .js en el sistema de archivos local mientras elude la política de acceso-control-permitir-origen con la que me encontré al intentar usar las funciones de jQuery.
Ok, he hecho muchos cambios y perdido mucho tiempo. Pero lo entendí. La solución en mi última respuesta funciona bien para Chrome y para Mozilla. Pero no funciona para el bendito IE, porque IE no disparará el evento onload: cree que ha tratado con todas las onloads en este archivo y no puede hacer que haga otro. Sin embargo, IE está feliz de cargar el archivo usando la función getScript de JQuery (que Chrome no permitirá debido a la política ccess-control-allow-origin); necesitará las bibliotecas de JQuery para que esto funcione. Así que esto es lo que terminé con:
function getMyText(){ var url='mylocalfile.js'; if (jQuery.support.scriptEval) { var old = document.getElementById('uploadScript'); if (old != null) { old.parentNode.removeChild(old); delete old; } var head = document.getElementsByTagName("head")[0]; var script = document.createElement('script'); script.id = 'uploadScript'; script.type = 'text/javascript'; script.onload = refresh_page; script.src = url; head.appendChild(script); } else { $.getScript(url,function(){ refresh_page(); }); } } function refresh_page() { alert(mytext); }En todo esto, mylocaltext.js define todo mi html como el contenido de una variable, mytext. Feo, pero funciona. jQuery.support.scriptEval es verdadero para los navegadores inteligentes que activan eventos de carga si cambia el DOM. IE no lo hace, por lo que lo envía a .getScript; Chrome y otros lo hacen, por lo que los envía al otro lado. De todos modos, esto funciona en archivos locales.
Interesante, pero ¿cómo puedo usar la misma técnica para cargar un archivo HTML completo? Problema similar al tuyo: tengo cientos de archivos HTML que quiero incluir dentro de una página web, dependiendo de lo que el usuario quiera ver. Parece que puedo usar esta técnica para cargar una página HTML completa, algo como:
script.id = 'uploadScript'; script.type = 'text/html'; script.src = url; script.onload = refresh_page; head.appendChild(script);es decir, dígale que se cargue en HTML. Puedo ver desde la consola que lo está cargando en la página y aparece el mensaje "Recurso interpretado como secuencia de comandos pero transferido con texto/html de tipo MIME". Pero no puedo encontrar ninguna forma de acceder al HTML cargado y retenido dentro del script