2012-05-16 32 views
9

Tôi đã thực hiện một số thử nghiệm ngày hôm nay liên quan đến cách chúng tôi có thể tải các tệp json với d3 vì tôi bị hấp dẫn bởi câu hỏi này: d3.json works but $.getJson fails. Tuy nhiên một số các bài kiểm tra mà tôi đã thực hiện là một chút khó khăn.d3.json, d3.xhr và các vấn đề liên miền chéo

d3.xhr("http://dbpedia.org/sparql?default-graph-uri=http%3A%2F%2Fdbpedia.org&query=select+*+where+%7B%3Chttp%3A%2F%2Fdbpedia.org%2Fresource%2FRoger_Federer%3E+%3Fp+%3Fo+filter%28lang%28%3Fo%29+%3D+%27en%27%29%7D%0D%0A&debug=on&timeout=&format=application%2Fsparql-results%2Bjson&save=display&fname=", function(data) 
console.log("success1"); 
alert(data); 
}); 

d3.json("http://dbpedia.org/sparql?default-graph-uri=http%3A%2F%2Fdbpedia.org&query=select+*+where+%7B%3Chttp%3A%2F%2Fdbpedia.org%2Fresource%2FRoger_Federer%3E+%3Fp+%3Fo+filter%28lang%28%3Fo%29+%3D+%27en%27%29%7D%0D%0A&debug=on&timeout=&format=application%2Fsparql-results%2Bjson&save=display&fname=", function(data){    console.log("success2"); 
alert(data); 
}); 


d3.xhr("http://api.worldbank.org/countries/BRA/indicators/BX.KLT.DINV.CD.WD?per_page=10&date=2007:2012&format=json", function(data){ 
console.log("success3"); 
alert(data); 
}) 

d3.json("http://api.worldbank.org/countries/BRA/indicators/BX.KLT.DINV.CD.WD?per_page=10&date=2007:2012&format=json", function(data){ 
console.log("success4"); 
alert(data); 
}) 

Tôi biết rằng vấn đề có thể liên quan đến ít nhất 2 lý do: kiểu MIME và CORS, nhưng tôi không thể hiểu được một vài điều khác:

  1. nếu gọi lại luôn thực hiện (thậm chí khó khăn đôi khi với OK 200 cũng có thể là một lỗi như được thấy từ các phương thức .ajax() và .getJSON() của jQuery. Tại sao tôi có thể xem dữ liệu chỉ trong một trường hợp (trường hợp đầu tiên) - phần còn lại của các trường hợp luôn luôn lỗi?

  2. loại MIME được hỗ trợ bằng phương pháp d3.xhr là gì?

  3. nếu d3.json chỉ là một trình bao bọc đẹp cho d3.xhr tại sao ví dụ 1 hoạt động và ví dụ 2 không hoạt động ...? Tôi muốn làm rõ một số. Tôi chủ yếu sử dụng d3 với các tập tin từ máy chủ của tôi, nhưng có những trường hợp như thế này khi tôi cũng phải sử dụng một số dữ liệu bên ngoài, và nó sẽ thực sự tốt đẹp để làm điều này cũng với D3, không chỉ với jQuery.

Tôi nghĩ rằng nên có danh sách với tất cả các loại MIME được chấp nhận theo các phương pháp này.

+0

lý do tôi cho yêu cầu này rất đơn giản: chúng tôi sẽ sử dụng D3 nặng nề cho visualizations dữ liệu được liên kết trong những tháng tiếp theo – paxRoman

Trả lời

12

Lý do tại sao yêu cầu đầu tiên thành công trong khi lần thứ hai không thực hiện được với cấu hình của máy chủ dbpedia.org. Chức năng d3.json() thực hiện hai điều:

  1. Nó đặt Accept tiêu đề để Mimetype application/json

  2. Nó phân tích các phản ứng sử dụng JSON.parse()

Số 1 là vấn đề - các dbpedia. máy chủ org đang trả về phản hồi của 406 (Unacceptable) cho tiêu đề Accept: application/json. Tôi không chắc tại sao điều này là đúng, nhưng với thông số URL bạn đang gửi, có vẻ như máy chủ mong muốn application/sparql-results+json thay vào đó - thực sự, chỉ định loại mime này với d3.xhr() thành công, trong khi sử dụng application/json không thành công.

Với dữ liệu của Ngân hàng Thế giới, yêu cầu không thành công vì máy chủ không phải là CORS-enabled. Cách duy nhất trong trình duyệt để thực hiện cuộc gọi đến một API từ xa mà không có CORS được bật là sử dụng JSONP (giả sử API hỗ trợ nó). Khi điều đó xảy ra, data.worldbank.com does support JSONP, nhưng D3 không - bạn sẽ cần phải tự mình xử lý hoặc sử dụng thư viện của bên thứ ba như jQuery để đưa ra yêu cầu. Nói chung, D3 không ưu tiên hỗ trợ AJAX mạnh mẽ theo cách jQuery và các thư viện khác, vì đó không phải là trọng tâm của nó - vì vậy nếu bạn muốn tải nhiều tài nguyên bên ngoài, bạn nên làm như vậy với Thư viện của bên thứ ba có hỗ trợ nhiều hơn cho các cuộc gọi AJAX được tinh chỉnh cẩn thận. Tùy thuộc vào thứ bạn muốn tải, tùy chọn khác là thiết lập proxy trên máy chủ của riêng bạn có thể gọi các API từ xa và sau đó cung cấp dữ liệu cho trực quan hóa của bạn thông qua cuộc gọi HTTP cục bộ - trong trường hợp đó tất cả trình tải của D3 nên làm việc tốt.

+1

Đối với Ngân hàng Thế giới, tôi muốn đề nghị sử dụng [Plugin d3.jsonp] (https://github.com/d3/d3-plugins/tree/master/jsonp). Bạn sẽ muốn sửa đổi nó mặc dù, để làm việc với [cấu trúc cuộc gọi WorldBank] (http://data.worldbank.org/node/11). Cấu trúc cuộc gọi sử dụng chuỗi truy vấn url '& prefix = callbackFunctionName' để chỉ định hàm gọi lại, trong khi plugin d3.jsonp mong đợi' & callback = callbackFunctionName'. Vì vậy, bạn có thể thay đổi dòng 10 và 24, thay thế từ 'callback' bằng' tiền tố' (xem [pastebin này] (http://pastebin.com/MLs0LaKW)). Sau đó, tạo một chức năng gọi lại để thực hiện khi trả lời. – wgardiner

0

Problematic ví dụ 1 là mất tích một cú đúp xoăn mở giữa

"chức năng (dữ liệu)" và "bàn giao".

Nó hoạt động cho tôi một lần viết lại như function(data) { console, vv

Các vấn đề liên quan