将本地JSON文件加载到变量中


113

我正在尝试将.json文件加载到javascript中的变量中,但无法正常工作。这可能只是一个小错误,但我找不到它。

当我使用静态数据时,一切工作正常:

var json = {
  id: "whatever",
  name: "start",
  children: [{
      "id": "0.9685",
      "name": " contents:queue"
    }, {
      "id": "0.79281",
      "name": " contents:mqq_error"
    }
  }]
}

我把一切的在{}一个content.json文件,并试图以加载到本地JavaScript变量作为解释在这里:负载JSON转换成变量

var json = (function() {
  var json = null;
  $.ajax({
    'async': false,
    'global': false,
    'url': "/content.json",
    'dataType': "json",
    'success': function(data) {
      json = data;
    }
  });
  return json;
})();

我使用Chrome调试器运行它,它总是告诉我该变量的json值为null。该content.json文件与调用它的.js文件位于同一目录中。

我错过了什么?


1
您的文件url /content.json表示该文件位于Web应用程序的根级别。更改为content.json(不带斜杠)以将其指向放置脚本文件的相同目录。仅在脚本文件位于根目录下的情况下,它才有效。
Samich

该文件位于WebContent \ jit \ content.json中。我尝试使用“ url”:“ / WebContent / jit / content.json”,但该变量仍为null
PogoMips

Answers:


38

如果content.json直接将对象粘贴到该对象,则它是无效的JSON。JSON键值必须用双引号("not ')包裹,除非该值是数字,布尔值null或复合值(数组或对象)。JSON不能包含函数或undefined值。以下是您作为有效JSON的对象。

{
  "id": "whatever",
  "name": "start",
  "children": [
    {
      "id": "0.9685",
      "name": " contents:queue"
    },
    {
      "id": "0.79281",
      "name": " contents:mqq_error"
    }
  ]
}

你也有一个额外的}


1
我不敢相信它已修复..为什么它将直接嵌入.js文件而不用双引号而不是.json文件呢?那没有任何意义……
PogoMips

16
@ user1695165-json和javascript对象是两个不同的东西,它们看起来相同。
adeneo 2013年

2
@Kevin B“ ...除非值是数字[或布尔值]。”
雅各布·博尚

1
提示:您可以使用jsonlint.com之类的json验证程序,以便在使用前检查json数据。
Marco Panichi

129

我的解决方案,如回答这里,是使用:

    var json = require('./data.json'); //with path

该文件仅加载一次,其他请求将使用缓存。

编辑为了避免缓存,以下是使用模块在注释中给出的此博客文章的帮助器功能fs

var readJson = (path, cb) => {
  fs.readFile(require.resolve(path), (err, data) => {
    if (err)
      cb(err)
    else
      cb(null, JSON.parse(data))
  })
}

48
只想指定此解决方案需要一个名为RequireJS的附加库。
路易斯·卡邦戈

4
如何避免缓存?
2011年

2
根据Guilherme Oenning的建议不推荐goenning.net/2016/04/14/stop-reading-json-files-with-require
Sangimed

2
TLDR;缓存在单元测试中给他造成了打击,因此他提供了一个帮助函数来避免缓存(ping @nono)。
Ehvince

@Ehvince哦,因为我没有阅读整篇文章,所以我没有注意到。谢谢您:-)
Sangimed

50

对于ES6 / ES2015,您可以像这样直接导入

// example.json
{
    "name": "testing"
}


// ES6/ES2015
// app.js
import * as data from './example.json';
const {name} = data;
console.log(name); // output 'testing'

如果使用Typescript,则可以声明json模块,例如:

// tying.d.ts
declare module "*.json" {
    const value: any;
    export default value;
}

从Typescript 2.9+开始,您可以添加-resolveJsonModule编译器选项tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
     ...
    "resolveJsonModule": true,
     ...
  },
  ...
}

5
导入在Chrome v72中不起作用-仍为Uncaught SyntaxError: Unexpected token *
1000Gbps,

2
当我使用它时,似乎data是一个模块,但却data.default是对象
Dustin Michels

1
我试图在控制台中运行它,但是没有成功。这不适用于带有babel-node 6.26.0的节点v12.4.0。我总是得到SyntaxError: Unexpected token *
mario199

2
对于ES6 / ES2015,您可以直接导入:似乎import * as data from './example.json'由于mime类型错误而在执行时出现控制台错误。
Fallenreaper

如果我使用的import * as data from './example.json';data是刚刚模块,但是data.default是对象。但是当我使用import data from './example.json';data是对象,这是更applicapable
内尔

4

有两个可能的问题:

  1. AJAX是异步的,因此json当您从外部函数返回时将是未定义的。加载文件后,回调函数将设置json为某个值,但那时没有人在乎了。

    我发现您尝试使用 'async': false。要检查是否可行,请将以下行添加到代码中,然后检查浏览器的控制台:

    console.log(['json', json]);
  2. 路径可能错误。使用与在HTML文档中加载脚本相同的路径。因此,如果您的脚本是js/script.js,请使用js/content.json

    某些浏览器可以向您显示他们尝试访问的URL以及访问的方式(成功/错误代码,HTML标头等)。检查浏览器的开发工具,看看会发生什么。


也许他的jquery版本不支持此功能?我改进了措辞。
亚伦·迪古拉2013年

4

内建 node.js模块fs将根据您的需要异步或同步执行该操作。

您可以使用 var fs = require('fs');

异步

fs.readFile('./content.json', (err, data) => {
    if (err)
      console.log(err);
    else {
      var json = JSON.parse(data);
    //your code using json object
    }
})

同步

var json = JSON.parse(fs.readFileSync('./content.json').toString());

-1

对于文件〜/ my-app / src / db / abc.json中的给定json格式:

  [
      {
        "name":"Ankit",
        "id":1
      },
      {
        "name":"Aditi",
        "id":2
      },
      {
        "name":"Avani",
        "id":3
      }
  ]

为了导入到〜/ my-app / src / app.js之类的.js文件:

 const json = require("./db/abc.json");

 class Arena extends React.Component{
   render(){
     return(
       json.map((user)=>
        {
          return(
            <div>{user.name}</div>
          )
        }
       )
      }
    );
   }
 }

 export default Arena;

输出:

Ankit Aditi Avani

这是对并非此处所问问题的答案。
凯文B

根据我的解释@KevinB,我将.json文件导入了.js文件。这帮助我将json文件加载到const json。从这里,我可以将以下json字典用于用户属性等等。
Ank_247shbm

很好,但是,这个问题是关于用户试图将对象文字复制到.json文件中,然后他们使用ajax加载的,这仅仅是因为他们的对象文字格式对于JSON无效。安装时发生反应,有需要一定会在某些情况下,工作导入此,它并没有真正帮助这个情况。
凯文B

请注意:在所有其他答案上发布链接到该答案的评论可被认为是过度的自我宣传,而尝试编辑答案是故意的。您的评论已被删除,请不要再进行这样的编辑。
布拉德·拉尔森

谢谢,对我来说太好了!
Qui-Gon Jinn
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.