Reading local XML using JS

Currently, due to the security policy, Chromium cannot read local files via ajax without --allow-file-access-from-files . But for now, I need to create a web application where the database is an xml file (in the worst case, json) located in the same directory as index.html. It is understood that the user can run this application locally. Are workarounds possible for reading an xml- (json-) file without wrapping it in a function and without changing the js extension?

 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); */ } } } 
+7
json javascript xml
source share
5 answers

Access to the file: protocol in chrome using the XMLHttpRequest() or <link> element without the --allow-file-access-from-files flag set when the chrome instance was started is not enabled by default.

--allow-file-access-from-files

By default, files: // URIs cannot read other files: // URIs. Override this for developers who need old behavior for testing.


Currently, due to security policies, Chromium cannot read local files via ajax without --allow-file-access-from-files . But I currently need to create a web application in which the database is an xml file (in the worst case, json) located in the same directory as index.html. It is understood that the user can run this application locally. Are there any workarounds for reading an xml- (json-) file without wrapping it in a function and changing to the js extension?

If the user knows that local files should be used by the application, you can use the <input type="file"> element so that the user can download the file from the user's local file system, process the file using FileReader , and then continue working with the application.

Else, tell the user that using the application requires running chrome with the --allow-file-access-from-files flag --allow-file-access-from-files , which can be done by creating a launcher for this, specifying a different user data directory for the chrome instance. Launcher may be, for example,

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

See also How to make the Google Chrome flag "-allow-file-access-from-files" permanent?

The above command can also be run on terminal

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

without creating a desktop; where when the chrome instance is closed, run

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

to delete the configuration folder for the chrome instance.

After the flag is set, the user can include the <link> element with the rel="import" and href attributes, pointing to the local file and type to "application/xml" , for an option other than XMLHttpRequest , to get the file. Access XML document using

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

See Is there a way to find out if the link is expecting / script or failed .


Another alternative, albeit more in demand, would be to use requestFileSystem to store the file in LocalFileSystem .

Cm.

  • How to use webkitRequestFileSystem in a file: protocol
  • JQuery file upload plugin: can I save the structure of downloaded folders?
  • How to write a file (user directory) using JavaScript?

Either create or modify a chrome app and use

 chrome.fileSystem 

See GoogleChrome / chrome-app-samples / filesystem-access .


The easiest approach is to provide means for downloading files through affirmative actions of the user; process the downloaded file, and then continue to work 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> 
+4
source share

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

instead of new ActiveXObject('Microsoft.XMLDOM') .

You can find the API through GOOGLE. Good luck.

+1
source share

If I understand correctly, the supplied product is designed to run locally, so you cannot set flags for local access to files on the user's computer. Something I did as a last resort was to build it as an executable file with something like nw.js and save the external data files. Otherwise, you are probably looking at loading as a script using the JSON schema in the JS file.

+1
source share

I had a similar problem. I decided to just embed the XML file in HTML using PHP. Since the application is loaded locally from disk, size, cache, etc., This is not a concern.

If you use Webpack, you can directly import the file using the bootloader, for example this or this , in which case the file is included in the javascript bundled.

+1
source share

You can load XML through a line of text using DOMParser . Just upload the file and .parseFromString text using .parseFromString , you can use the if statement containing (window.DOMParser) to check if DOMParser is supported

+1
source share

All Articles