如何通过Python/Flask/Jinja在D3.js中加载外部(跨域)JSON?
[我对所有标记的语言都很陌生,请多多包涵!]
我正在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)
我想问的是:
- 我该如何把下载的JSON数据传递给d3的“绘图”函数?
- 为什么我不能把我的json_response变量传给d3.json,这样会返回
Uncaught TypeError: Cannot read property 'objects' of undefined
的错误? - 为什么我不能直接从网址加载数据到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 一模一样,也让我重新检查了一遍我的代码,看看有没有错误。