加载本地JSON文件

Pat*_*wne 299 javascript jquery firebug json local-files

我正在尝试加载本地JSON文件,但它无法正常工作.这是我的JavaScript代码(使用jQuery:

var json = $.getJSON("test.json");
var data = eval("(" +json.responseText + ")");
document.write(data["a"]);
Run Code Online (Sandbox Code Playgroud)

test.json文件:

{"a" : "b", "c" : "d"}
Run Code Online (Sandbox Code Playgroud)

没有显示任何内容,Firebug告诉我数据未定义.在Firebug中,我可以看到json.responseText并且它是好的和有效的,但是当我复制该行时很奇怪:

 var data = eval("(" +json.responseText + ")");
Run Code Online (Sandbox Code Playgroud)

在Firebug的控制台中,它可以工作,我可以访问数据.

有人有解决方案吗?

sep*_*010 272

$.getJSON 是异步的所以你应该这样做:

$.getJSON("test.json", function(json) {
    console.log(json); // this will show the info it in firebug console
});
Run Code Online (Sandbox Code Playgroud)

  • 你真的被允许访问本地文件吗? (42认同)
  • 完全正确.Chromes的安全性比Firefox或其他人要严格得多.使用xhr,Josn,Xml等加载任何东西几乎都被锁定在Chrome中,除了一两件事. (15认同)
  • 我认为本地文件在Firefox中运行良好,但在Chrome中运行不正常. (14认同)
  • 我建议使用http://myjson.com/上传您的本地文件并从Chrome浏览器访问它. (8认同)
  • 不,它不能是文件,但必须由网络服务器提供服务。 (5认同)
  • 我尝试过这个,但没有运气。控制台也没有错误:( (2认同)
  • 如果您使用 --allow-file-access-from-files 标志启动 Chrome,Chrome 允许您访问本地 JSON 或其他数据文件。我用上面的代码在版本 34.0.1847.131 m 上检查了这一点;它也应该适用于其他版本。 (2认同)
  • 我有一个本地应用程序,可以读取文件,如果我使用 Firefox 并将 file.uri.strict 设置为 false 就可以了。是的,否则,你需要一个服务器,或者一个 Chrome 的服务器插件。 (2认同)

Ehv*_*nce 154

我有同样的需求(测试我的angularjs应用程序),我找到的唯一方法是使用require.js:

var json = require('./data.json'); //(with path)
Run Code Online (Sandbox Code Playgroud)

注意:文件加载一次,进一步调用将使用缓存.

有关使用nodejs读取文件的更多信息:http://docs.nodejitsu.com/articles/file-system/how-to-read-files-in-nodejs

require.js:http: //requirejs.org/

  • require 不适用于浏览器,因为它是 node.js 模块。如果OP想在浏览器中加载它,应该使用fetch是正确的解决方案。 (5认同)
  • 如果你用jest做这个,那么记得做`jest.dontMock('./ data.json');`或者结果是空的.可能对那里的人有用:) (4认同)
  • 请提供完整的示例:我收到错误消息:`尚未为上下文_加载。使用require([])` (3认同)
  • 是的,require 用于 Node,但 requireJS 也可以在浏览器中使用:“RequireJS 是一个 JavaScript 文件和模块加载器。它针对浏览器内使用进行了优化,但它也可以在其他 JavaScript 环境中使用,例如 Rhino 和 Node。 ” (2认同)

小智 77

如果要让用户选择本地json文件(文件系统上的任何位置),则以下解决方案有效.

它使用FileReader和JSON.parser(并且没有jquery).

<html>
<body>

<form id="jsonFile" name="jsonFile" enctype="multipart/form-data" method="post">

  <fieldset>
    <h2>Json File</h2>
     <input type='file' id='fileinput'>
     <input type='button' id='btnLoad' value='Load' onclick='loadFile();'>
  </fieldset>
</form>


<script type="text/javascript">

  function loadFile() {
    var input, file, fr;

    if (typeof window.FileReader !== 'function') {
      alert("The file API isn't supported on this browser yet.");
      return;
    }

    input = document.getElementById('fileinput');
    if (!input) {
      alert("Um, couldn't find the fileinput element.");
    }
    else if (!input.files) {
      alert("This browser doesn't seem to support the `files` property of file inputs.");
    }
    else if (!input.files[0]) {
      alert("Please select a file before clicking 'Load'");
    }
    else {
      file = input.files[0];
      fr = new FileReader();
      fr.onload = receivedText;
      fr.readAsText(file);
    }

    function receivedText(e) {
      let lines = e.target.result;
      var newArr = JSON.parse(lines); 
    }
  }
</script>

</body>
</html>
Run Code Online (Sandbox Code Playgroud)

这是FileReader的一个很好的介绍:http://www.html5rocks.com/en/tutorials/file/dndfiles/

  • IE 8或9不支持FileReader API,但所有其他浏览器都可以:http://caniuse.com/#search=filereader (3认同)

alo*_*ica 74

以更现代的方式,您现在可以使用Fetch API:

fetch("test.json")
  .then(response => response.json())
  .then(json => console.log(json));
Run Code Online (Sandbox Code Playgroud)

所有现代浏览器都支持Fetch API.(Internet Explorer没有,但Edge确实!)

资源:

  • 使用 Fetch API 时,是否仍然禁止访问本地文件,除非您禁用安全设置? (9认同)
  • @LarsH 显然是的,我今天早上试过了,fetch api 无法读取带有 file:// 方案的本地 json 文件。这种方法看起来很干净,但你不能将它用于本地文件 (7认同)
  • 无法使用 fetch API 访问本地文件 (5认同)
  • fetch 仅支持 HTTP(S) 协议! (4认同)
  • @keysl 好吧,我想出于安全原因可能必须是这样。(你是对的,我的意思是“禁止通过‘file://’方案访问文件。)但这是一个很好的干净方法。由于这个答案,我已经开始使用它了。 (2认同)

jwe*_*rre 69

如果您正在寻找快速而又脏的东西,只需将数据加载到HTML文档的头部即可.

data.js

var DATA = {"a" : "b", "c" : "d"};
Run Code Online (Sandbox Code Playgroud)

的index.html

<html>
<head>
   <script src="data.js" ></script>
   <script src="main.js" ></script>
</head>
...
</html>
Run Code Online (Sandbox Code Playgroud)

main.js

(function(){
   console.log(DATA); // {"a" : "b", "c" : "d"}
})();
Run Code Online (Sandbox Code Playgroud)

  • @PatrickBrowne是的,getJSON是一个很好的解决方案,但我认为在很多情况下你会遇到跨域问题(例如从S3加载数据). (7认同)
  • 老实说,如果您只有一些预先保存的数据并且想要提供静态页面,那么这是一个很好的解决方案 (2认同)

xgq*_*rms 15

ace.webgeeker.xyz

function loadJSON(callback) {
    var xobj = new XMLHttpRequest();
    xobj.overrideMimeType("application/json");
    xobj.open('GET', 'my_data.json', true);
    // Replace 'my_data' with the path to your file
    xobj.onreadystatechange = function() {
        if (xobj.readyState === 4 && xobj.status === "200") {
            // Required use of an anonymous callback 
            // as .open() will NOT return a value but simply returns undefined in asynchronous mode
            callback(xobj.responseText);
        }
    };
    xobj.send(null);
}

function init() {
    loadJSON(function(response) {
        // Parse JSON string into object
        var actual_JSON = JSON.parse(response);
    });
}
Run Code Online (Sandbox Code Playgroud)

ES6版本

const loadJSON = (callback) => {
    let xobj = new XMLHttpRequest();
    xobj.overrideMimeType("application/json");
    xobj.open('GET', 'my_data.json', true);
    // Replace 'my_data' with the path to your file
    xobj.onreadystatechange = () => {
        if (xobj.readyState === 4 && xobj.status === "200") {
            // Required use of an anonymous callback 
            // as .open() will NOT return a value but simply returns undefined in asynchronous mode
            callback(xobj.responseText);
        }
    };
    xobj.send(null);
}

const init = () => {
    loadJSON((response) => {
        // Parse JSON string into object
        let actual_JSON = JSON.parse(response);
    });
}
Run Code Online (Sandbox Code Playgroud)

  • 问题明确指出“本地文件”,因此不是通过 HTTP。 (4认同)
  • //xobj.status是整数xobj.status ===“ 200”应该是xobj.status === 200 (2认同)
  • @xgqfrms 在线演示不会重现 file:// URL 发生的情况。 (2认同)

Mar*_*ark 15

从头开始添加到您的 JSON 文件

var object1 = [
Run Code Online (Sandbox Code Playgroud)

最后

]
Run Code Online (Sandbox Code Playgroud)

保存

然后用纯js加载它

<script type="text/javascript" src="1.json"></script>
Run Code Online (Sandbox Code Playgroud)

现在你可以将它用作 object1 - 它已经加载了!

在 Chrome 中完美运行,无需任何额外的库

  • 但最好将其重命名为“1.js” (2认同)

小智 10

我不敢相信在没有理解和/或解决原始海报的实际代码问题的情况下已经回答了多少次这个问题.那就是说,我自己就是初学者(只有2个月的编码).我的代码确实可以正常工作,但随时可以建议对其进行任何更改. 这是解决方案:

//include the   'async':false   parameter or the object data won't get captured when loading
var json = $.getJSON({'url': "http://spoonertuner.com/projects/test/test.json", 'async': false});  

//The next line of code will filter out all the unwanted data from the object.
json = JSON.parse(json.responseText); 

//You can now access the json variable's object data like this json.a and json.c
document.write(json.a);
console.log(json);
Run Code Online (Sandbox Code Playgroud)

这是编写上面提供的相同代码的更简短方法:

var json = JSON.parse($.getJSON({'url': "http://spoonertuner.com/projects/test/test.json", 'async': false}).responseText);
Run Code Online (Sandbox Code Playgroud)

您也可以使用$ .ajax而不是$ .getJSON以完全相同的方式编写代码:

var json = JSON.parse($.ajax({'url': "http://spoonertuner.com/projects/test/test.json", 'async': false}).responseText); 
Run Code Online (Sandbox Code Playgroud)

最后,最后一种方法是将$ .ajax包装在一个函数中.我不能相信这一点,但我确实修改了一下.我测试了它,它的工作原理与我上面的代码产生的结果相同.我在这里找到了这个解决方案 - >将json加载到变量中

var json = function () {
    var jsonTemp = null;
    $.ajax({
        'async': false,
        'url': "http://spoonertuner.com/projects/test/test.json",
        'success': function (data) {
            jsonTemp = data;
        }
    });
    return jsonTemp;
}(); 

document.write(json.a);
console.log(json);
Run Code Online (Sandbox Code Playgroud)

您在上面的代码中看到的test.json文件托管在我的服务器上,并包含他(原始海报)发布的相同json数据对象.

{
    "a" : "b",
    "c" : "d"
}
Run Code Online (Sandbox Code Playgroud)

  • 您不明白问题中“本地文件”的含义:不是 HTTP。 (7认同)

Ogg*_*las 10

我很惊讶从es6导入没有被提及(使用小文件)

例如: import test from './test.json'

webpack 2 <使用文件的json-loader默认值.json.

https://webpack.js.org/guides/migrating/#json-loader-is-not-required-anymore

对于TypeScript:

import test from 'json-loader!./test.json';
Run Code Online (Sandbox Code Playgroud)

TS2307(TS)找不到模块'json-loader!./ suburbs.json'

为了让它工作,我必须先声明模块.我希望这会为某人节省几个小时.

declare module "json-loader!*" {
  let json: any;
  export default json;
}

...

import test from 'json-loader!./test.json';
Run Code Online (Sandbox Code Playgroud)

如果我试图省略loader,json-loader我收到以下错误webpack:

BREAKING CHANGE:使用加载器时不再允许省略'-loader'后缀.您需要指定'json-loader'而不是'json',请参阅https://webpack.js.org/guides/migrating/#automatic-loader-module-name-extension-removed

  • 当网页使用 file: 协议加载时,无法使用 es6 import 语句。 (3认同)
  • 简单明了。 (2认同)

Sam*_*ich 6

尝试就是这样(但请注意,JavaScript无法访问客户端文件系统):

$.getJSON('test.json', function(data) {
  console.log(data);
});
Run Code Online (Sandbox Code Playgroud)


ns-*_*-1m 6

最近D3js能够处理本地json文件.

这是问题 https://github.com/mbostock/d3/issues/673

这是补丁,以便D3使用本地json文件. https://github.com/mbostock/d3/pull/632

  • 通过使用D3读取json文件的示例,可以大大改善这个答案. (4认同)

Sup*_*nda 6

我所做的就是稍微编辑一下 JSON 文件。

myfile.json=>myfile.js

在JSON文件中,(使其成为JS变量)

{name: "Whatever"}=>var x = {name: "Whatever"}

在最后,

export default x;

然后,

import JsonObj from './myfile.js';


Tec*_*pud 5

尝试(不成功)加载本地 json 文件时发现此线程。这个解决方案对我有用......

function load_json(src) {
  var head = document.getElementsByTagName('head')[0];

  //use class, as we can't reference by id
  var element = head.getElementsByClassName("json")[0];

  try {
    element.parentNode.removeChild(element);
  } catch (e) {
    //
  }

  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = src;
  script.className = "json";
  script.async = false;
  head.appendChild(script);

  //call the postload function after a slight delay to allow the json to load
  window.setTimeout(postloadfunction, 100)
}
Run Code Online (Sandbox Code Playgroud)

......并且像这样使用......

load_json("test2.html.js")
Run Code Online (Sandbox Code Playgroud)

......这是<head>......

<head>
  <script type="text/javascript" src="test.html.js" class="json"></script>
</head>
Run Code Online (Sandbox Code Playgroud)

  • 这似乎不是很可重用。例如,如果 json 文件由远程服务器提供,则 100 毫秒超时可能不足以加载。由于时间取决于客户端的连接速度,因此您必须为连接速度较慢的客户端设置很长的超时时间。简而言之, setTimeout 不应该用于等待资源加载。 (2认同)
  • 我不是建议无限等待,我建议使用一种技术,允许您在文件加载完成后立即做出反应。我的超时问题是,您总是必须等待它完成。即使文件会在 10 毫秒内加载,您仍然需要等待 100 毫秒。是的,调整超时很容易,但您的建议是每次要加载不同的文件或文件大小更改时(以优化等待)更改代码。这样的解决方案恕我直言是错误的,将来可能会引起很多麻烦,尤其是当其他人尝试使用它时。 (2认同)

teh*_*nsi 5

在 TypeScript 中,您可以使用 import 加载本地 JSON 文件。例如加载 font.json:

import * as fontJson from '../../public/fonts/font_name.json';
Run Code Online (Sandbox Code Playgroud)

这需要一个 tsconfig 标志 --resolveJsonModule:

// tsconfig.json

{
    "compilerOptions": {
        "module": "commonjs",
        "resolveJsonModule": true,
        "esModuleInterop": true
    }
}
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅 typescript 的发行说明:https : //www.typescriptlang.org/docs/handbook/release-notes/typescript-2-9.html