如何通过Python/Flask/Jinja在D3.js中加载外部(跨域)JSON?

0 投票
1 回答
1672 浏览
提问于 2025-04-18 08:59

[我对所有标记的语言都很陌生,请多多包涵!]

我正在Heroku上开发一个小应用,使用d3.js在世界地图上展示JSON数据。

我想直接从一个网址加载JSON到d3.js,但在我的本地环境中,这个请求被客户端阻止了。

GET http://earthquake-report.com/feeds/recent-eq?json net::ERR_BLOCKED_BY_CLIENT

据我所知,从另一个域名直接用JavaScript加载数据是不允许的,而且这通常是服务器端的配置,而我在Heroku上肯定没有权限去改这些。

所以我想了个办法,先用Python来加载数据,代码如下:

earthquake_url = "http://earthquake-report.com/feeds/recent-eq?json"
response = urllib2.urlopen(earthquake_url)
json_response = json.load(response)

然后我通过jinja参数把Python中的JSON数据传递给d3.js:

return render_template('main.html', json_response=json.dumps(json_response), **templateData)

在JavaScript那边,下面的代码可以让我得到一个对象,这个对象和从本地文件加载的JSON一模一样:

var json_response = {{ json_response|safe }}
console.log(json_response)

queue()
    .defer(d3.json, "/static/js/readme-world.json")
    .defer(d3.json, "/static/js/earthquake.json")
    .await(ready);

function ready(error, world, data) {
    console.log(data)

我想问的是:

  1. 我该如何把下载的JSON数据传递给d3的“绘图”函数?
  2. 为什么我不能把我的json_response变量传给d3.json,这样会返回Uncaught TypeError: Cannot read property 'objects' of undefined的错误?
  3. 为什么我不能直接从网址加载数据到d3?

1 个回答

2

好吧,看起来我之前有点傻。我把这段代码改成了这样:

queue()
    .defer(d3.json, "/static/js/readme-world.json")
    .defer(d3.json, "/static/js/earthquake.json")
    .await(ready);

function ready(error, world, data) {
    console.log(data)

变成了这样:

queue()
    .defer(d3.json, "/static/js/readme-world.json")

    .await(ready);

function ready(error, world) {
    console.log(data)

然后我把我的 json_response 插入到数据合并的代码中,像这样:

var g = svg.append("g");

        g.selectAll("circle")
           .data(json_response)
           .enter()
           .append("circle")

结果成功了!

对我帮助很大的是在 queue 后面加了一个 debug; 语句,这样我就能看到所有东西的状态。这确认了 json_response 确实和 earthquake.json 一模一样,也让我重新检查了一遍我的代码,看看有没有错误。

撰写回答