草庐IT

javascript - 用 JS 读取本地 XML

coder 2024-06-24 原文

目前,由于 security policy Chromium如果没有 --allow-file-access-from-files,则无法通过 ajax 读取本地文件。但是我目前需要创建一个 web 应用程序,其中数据库是一个 xml 文件(在极端情况下是 json),位于一个带有 index.html 的目录中。据了解,用户可以在本地运行这个应用程序。是否有读取 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);
             */
        }

    }
}

最佳答案

正在访问 file:使用 XMLHttpRequest() 的 Chromium 协议(protocol)或 <link>没有 --allow-file-access-from-files 的元素默认情况下不启用在 chromium 实例启动时设置的标志。

--allow-file-access-from-files

By default, file:// URIs cannot read other file:// URIs. 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. 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. 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?

如果用户知道应用程序将使用本地文件,您可以使用 <input type="file">用户从用户本地文件系统上传文件的元素,使用 FileReader 处理文件,然后继续申请。

否则,建议用户使用应用程序需要使用 --allow-file-access-from-files 启动 Chrome 标志集,这可以通过为此目的创建一个启动器来完成,为 chromium 实例指定一个不同的用户数据目录。例如,启动器可以是

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

另见 How do I make the Google Chrome flag “--allow-file-access-from-files” permanent?

上述命令也可以在 terminal 运行

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

无需创建桌面启动器;当 chromium 实例关闭时在哪里运行

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

删除 chromium 实例的配置文件夹。

设置标志后,用户可以包含 <link>带有 rel="import" 的元素属性和 href指向本地文件和type设置为 "application/xml" , 对于 XMLHttpRequest 以外的选项获取文件。访问XML document使用

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

参见 Is there a way to know if a link/script is still pending or has it failed .


另一种替代方案,虽然涉及更多,但会使用 requestFileSystem将文件存储在 LocalFileSystem .

或者创建或修改 chrome 应用程序并使用

chrome.fileSystem

参见 GoogleChrome/chrome-app-samples/filesystem-access .


最简单的方法是提供一种通过肯定的用户操作上传文件的方法;处理上传的文件,然后继续申请。

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>

关于javascript - 用 JS 读取本地 XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41279589/

有关javascript - 用 JS 读取本地 XML的更多相关文章

  1. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  2. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  3. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  4. Ruby 写入和读取对象到文件 - 2

    好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信

  5. ruby - 是否可以覆盖 gemfile 进行本地开发? - 2

    我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI

  6. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  7. python - 如何读取 MIDI 文件、更改其乐器并将其写回? - 2

    我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的

  8. STM32读取串口传感器数据(颗粒物传感器,主动上传) - 2

    文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,

  9. ruby - 是否可以在不实际发送或读取数据的情况下查明 ruby​​ 套接字是否处于 ESTABLISHED 或 CLOSE_WAIT 状态? - 2

    s=Socket.new(Socket::AF_INET,Socket::SOCK_STREAM,0)s.connect(Socket.pack_sockaddr_in('port','hostname'))ssl=OpenSSL::SSL::SSLSocket.new(s,sslcert)ssl.connect从这里开始,如果ssl连接和底层套接字仍然是ESTABLISHED,或者它是否在默认值7200之后进入CLOSE_WAIT,我想检查一个线程几秒钟甚至更糟的是在实际上不需要.write()或.read()的情况下关闭。是用select()、IO.select()还是其他方法完成

  10. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

随机推荐