javascript - Leer XML local con JS
json (5)
Por el momento, debido a la
política de seguridad, Chromium
no puede leer archivos locales a través de ajax sin
--allow-file-access-from-files
.
Pero actualmente necesito crear una aplicación web donde la base de datos es un archivo xml (en el caso extremo, json), ubicado en un directorio con index.html.
Se entiende que el usuario puede ejecutar esta aplicación localmente.
¿Hay soluciones para leer el archivo xml- (json-), sin envolverlo en una función y cambiar a la extensión js?
loadXMLFile(''./file.xml'').then(xml => {
// working with xml
});
function loadXMLFile(filename) {
return new Promise(function(resolve, reject) {
if(''ActiveXObject'' in window) {
// If is IE
var xmlDoc = new ActiveXObject(''Microsoft.XMLDOM'');
xmlDoc.async = false;
xmlDoc.load(filename);
resolve(xmlDoc.xml);
} else {
/*
* how to read xml file if is not IE?
* ...
* resolve(something);
*/
}
}
}
Acceso al
file:
protocolo en chromium usando
XMLHttpRequest()
o el elemento
<link>
sin el
--allow-file-access-from-files
establecido en el inicio de la instancia de
--allow-file-access-from-files
no está habilitado de manera predeterminada.
--allow-file-access-from-files
De forma predeterminada, el archivo: // URI no puede leer otro archivo: // URI. Esta es una anulación para los desarrolladores que necesitan el comportamiento anterior para las pruebas.
Por el momento, debido a la política de seguridad, Chromium no puede leer archivos locales a través de ajax sin
--allow-file-access-from-files
. Pero actualmente necesito crear una aplicación web donde la base de datos es un archivo xml (en el caso extremo, json), ubicado en un directorio con index.html. Se entiende que el usuario puede ejecutar esta aplicación localmente. ¿Hay soluciones para leer el archivo xml- (json-), sin envolverlo en una función y cambiar a la extensión js?
Si el usuario sabe que la aplicación debe usar archivos locales, puede utilizar el elemento
<input type="file">
para que el usuario cargue el archivo desde el sistema de archivos local del usuario, procese el archivo usando
FileReader
y luego continúe con la aplicación.
De lo contrario, avise al usuario que el uso de la aplicación requiere iniciar
--allow-file-access-from-files
con el
--allow-file-access-from-files
, que se puede hacer creando un iniciador para este propósito, especificando un directorio de datos de usuario diferente para la instancia de chromium.
El lanzador podría ser, por ejemplo
/usr/bin/chromium-browser --user-data-dir="/home/user/.config/chromium-temp" --allow-file-access-from-files
Consulte también ¿Cómo hago que la bandera de Google Chrome "--allow-file-access-from-files" sea permanente?
El comando anterior también se puede ejecutar en la
terminal
$ /usr/bin/chromium-browser --user-data-dir="/home/user/.config/chromium-temp" --allow-file-access-from-files
sin crear un lanzador de escritorio; donde cuando se cierra la instancia de cromo
$ rm -rf /home/user/.config/chromium-temp
para eliminar la carpeta de configuración para la instancia de chromium.
Una vez que se establece el indicador, el usuario puede incluir el elemento
<link>
con el
rel="import"
y
href
apuntando al archivo local y
type
set a
"application/xml"
, para la opción que no sea
XMLHttpRequest
para obtener el archivo.
Acceda al
document
XML
utilizando
const doc = document.querySelector("link[rel=import]").import;
Consulte ¿Hay alguna manera de saber si un enlace / script aún está pendiente o si ha fallado ?
Otra alternativa, aunque más complicada, sería utilizar
requestFileSystem
para almacenar el archivo en
LocalFileSystem
.
Ver
- Cómo usar webkitRequestFileSystem en el archivo: protocolo
- Complemento de carga de archivos jQuery: ¿Es posible preservar la estructura de las carpetas cargadas?
- ¿Cómo escribir en un archivo (directorio de usuarios) usando JavaScript?
O cree o modifique una aplicación de Chrome y use
chrome.fileSystem
Consulte GoogleChrome/chrome-app-samples/filesystem-access .
El enfoque más simple sería proporcionar un medio para cargar archivos mediante la acción afirmativa del usuario; procesar el archivo cargado, luego continuar con la aplicación.
const reader = new FileReader;
const parser = new DOMParser;
const startApp = function startApp(xml) {
return Promise.resolve(xml || doc)
};
const fileUpload = document.getElementById("fileupload");
const label = document.querySelector("label[for=fileupload]");
const handleAppStart = function handleStartApp(xml) {
console.log("xml document:", xml);
label.innerHTML = currentFileName + " successfully uploaded";
// do app stuff
}
const handleError = function handleError(err) {
console.error(err)
}
let doc;
let currentFileName;
reader.addEventListener("loadend", handleFileRead);
reader.addEventListener("error", handleError);
function handleFileRead(event) {
label.innerHTML = "";
currentFileName = "";
try {
doc = parser.parseFromString(reader.result, "application/xml");
fileUpload.value = "";
startApp(doc)
.then(function(data) {
handleAppStart(data)
})
.catch(handleError);
} catch (e) {
handleError(e);
}
}
function handleFileUpload(event) {
let file = fileUpload.files[0];
if (/xml/.test(file.type)) {
reader.readAsText(file);
currentFileName = file.name;
}
}
fileUpload.addEventListener("change", handleFileUpload)
<input type="file" name="fileupload" id="fileupload" accept=".xml" />
<label for="fileupload"></label>
Puede cargar XML a través de una cadena de texto usando
DOMParser
, simplemente cargue su archivo y analice el texto usando
.parseFromString
.
Puede usar una instrucción if que contenga
(window.DOMParser)
para verificar si DOMParser es compatible
Si entiendo correctamente, el entregable está destinado a ejecutarse localmente, por lo que no podrá establecer ningún indicador para el acceso a archivos locales en la máquina de un usuario. Algo que he hecho en un apuro es empacarlo como un ejecutable con algo como nw.js y mantener los archivos de datos externos. De lo contrario, probablemente esté buscando cargar como script usando un esquema JSON en un archivo JS.
Tuve un problema similar antes. Lo resolví simplemente incrustando el archivo XML en el HTML usando PHP. Dado que la aplicación se carga localmente desde el disco, el tamaño, el caché, etc. no son una preocupación.
Si está utilizando Webpack, puede importar directamente el archivo utilizando un cargador como this o this , en cuyo caso el archivo se incluye en el paquete de JavaScript resultante.
use
document.implementation.createDocument("", "", null)
en lugar del
new ActiveXObject(''Microsoft.XMLDOM'')
.
Puedes encontrar la API a través de GOOGLE. Buena suerte.