简体   繁体   English

使用JS读取本地XML

[英]Read local XML with JS

At the moment, due to the security policy Chromium can not read local files via ajax without --allow-file-access-from-files . 目前,由于安全政策,如果没有--allow-file-access-from-files Chromium无法通过ajax读取本地--allow-file-access-from-files But I currently need to create a web application where the database is a xml-file (in the extreme case, json), located in one dir with index.html. 但是我目前需要创建一个Web应用程序,其中数据库是xml文件(在极端情况下为json),位于index.html的一个目录中。 It is understood that the user can run this application locally. 可以理解,用户可以在本地运行该应用程序。 Are there workarounds for reading xml- (json-) file, without wrapping it in a function and change to js extension? 有没有读取xml-(json-)文件而不将其包装在函数中并更改为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);
             */
        }

    }
}

Accessing file: protocol at chromium using XMLHttpRequest() or <link> element without --allow-file-access-from-files flag set at chromium instance launch is not enabled by default. 访问file:在铬实例启动时,使用XMLHttpRequest()<link>元素在铬上的协议XMLHttpRequest()未设置--allow-file-access-from-files标志)默认情况下未启用。

--allow-file-access-from-files

By default, file:// URIs cannot read other file:// URIs. 默认情况下,file:// URI无法读取其他file:// URI。 This is an override for developers who need the old behavior for testing. 对于需要旧行为进行测试的开发人员来说,这是一个替代。


At the moment, due to the security policy Chromium can not read local files via ajax without --allow-file-access-from-files . 目前,由于安全政策,如果没有--allow-file-access-from-files Chromium无法通过ajax读取本地--allow-file-access-from-files But I currently need to create a web application where the database is a xml-file (in the extreme case, json), located in one dir with index.html. 但是我目前需要创建一个Web应用程序,其中数据库是xml文件(在极端情况下为json),位于index.html的一个目录中。 It is understood that the user can run this application locally. 可以理解,用户可以在本地运行该应用程序。 Are there workarounds for reading xml- (json-) file, without wrapping it in a function and change to js extension? 有没有读取xml-(json-)文件而不将其包装在函数中并更改为js扩展名的解决方法?

If user is aware that local files are to be used by the application you can utilize <input type="file"> element for user to upload file from user local filesystem, process file using FileReader , then proceed with application. 如果用户知道应用程序将使用本地文件,则可以使用<input type="file">元素让用户从用户本地文件系统上载文件,使用FileReader处理文件,然后继续进行应用程序。

Else, advise user that use of application requires launching chromium with --allow-file-access-from-files flag set, which can be done by creating a launcher for this purpose, specifying a different user data directory for the instance of chromium. 否则,建议用户使用应用程序需要启动带有--allow-file-access-from-files标志集的铬,可以通过为此目的创建启动器,为铬实例指定不同的用户数据目录来完成。 The launcher could be, for example 例如,启动器可以是

/usr/bin/chromium-browser --user-data-dir="/home/user/.config/chromium-temp" --allow-file-access-from-files

See also How do I make the Google Chrome flag “--allow-file-access-from-files” permanent? 另请参阅如何使Google Chrome浏览器标志“ --allow-file-access-from-files”永久保存?

The above command could also be run at terminal 上面的命令也可以在terminal上运行

$ /usr/bin/chromium-browser --user-data-dir="/home/user/.config/chromium-temp" --allow-file-access-from-files

without creating a desktop launcher; 无需创建桌面启动器; where when the instance of chromium is closed run 铬实例关闭的地方

$ rm -rf /home/user/.config/chromium-temp

to remove the configuration folder for the instance of chromium. 删除铬实例的配置文件夹。

Once the flag is set, user can include <link> element with rel="import" attribute and href pointing to local file and type set to "application/xml" , for option other than XMLHttpRequest to get file. 设置标志后,用户可以包括具有rel="import"属性的<link>元素和指向本地文件的href ,并将type设置为"application/xml" ,以获得XMLHttpRequest以外的选项来获取文件。 Access XML document using 使用访问XML document

const doc = document.querySelector("link[rel=import]").import;

See Is there a way to know if a link/script is still pending or has it failed . 请参阅是否有办法知道链接/脚本是否仍在挂起或失败


Another alternative, though more involved, would be to use requestFileSystem to to store the file at LocalFileSystem . 尽管涉及更多,但另一种替代方法是使用requestFileSystem将文件存储在LocalFileSystem

See 看到

Or create or modify a chrome app and use 或创建或修改Chrome应用并使用

chrome.fileSystem

See GoogleChrome/chrome-app-samples/filesystem-access . 请参阅GoogleChrome / chrome-app-samples / filesystem-access


The simplest approach would be to provide a means for file upload by affirmative user action; 最简单的方法是提供一种通过肯定的用户操作上传文件的方法; process the uploaded file, then proceed with the application. 处理上载的文件,然后继续执行该应用程序。

 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> 

use document.implementation.createDocument("", "", null) 使用document.implementation.createDocument("", "", null)

instead of new ActiveXObject('Microsoft.XMLDOM') . 而不是new ActiveXObject('Microsoft.XMLDOM')

You can find the API through GOOGLE. 您可以通过GOOGLE找到该API。 Good luck. 祝好运。

If I understand correctly, the deliverable is intended to run locally so you will not be able to set any flags for local file access on a user's machine. 如果我理解正确,则可交付结果旨在在本地运行,因此您将无法为用户计算机上的本地文件访问设置任何标志。 Something I've done in a pinch is to pack it up as an executable with something like nw.js and keep the external data files. 我紧要关头所做的就是将其打包为可执行文件,例如nw.js并保留外部数据文件。 Otherwise, you're probably looking at loading as script using a JSON schema in a JS file. 否则,您可能正在考虑使用JS文件中的JSON模式作为脚本加载。

I had a similar problem before. 我以前也有类似的问题。 I solved by simply embedding the XML file into the HTML using PHP. 我通过使用PHP将XML文件嵌入HTML来解决。 Since the application is loaded locally from disk, size, cache etc. are not a concern. 由于应用程序是从磁盘本地加载的,因此不需要担心大小,缓存等。

If you're using Webpack, you can instead directly import the file using a loader like this or this , in which case the file is included into the resulting bundled javascript. 如果您使用的是Webpack,则可以使用类似thisthis的加载程序直接导入文件,在这种情况下,文件将包含在生成的捆绑javascript中。

You can load XML through a string of text using DOMParser , Just load your file and parse the text using the .parseFromString . 您可以使用DOMParser通过文本字符串加载XML,只需加载文件并使用.parseFromString解析文本。 You could use an if statement containing (window.DOMParser) to check if the DOMParser is supported 您可以使用包含(window.DOMParser)的if语句来检查是否支持DOMParser

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM