Support for XmlHttpRequest+CORS in addition to just plain jsonp.

We try XHR first, since it supposedly returns better error messages (not
always true).  Then fall back to jsonp if it doesn't work.
diff --git a/render.js b/render.js
index 8cd2f7d..c9bc33b 100644
--- a/render.js
+++ b/render.js
@@ -1642,9 +1642,30 @@
   }
 
 
-  function getUrlData(url, success_func, error_func) {
-    console.debug('fetching data url:', url);
+  function extractJsonFromJsonp(text, success_func) {
+    var data = text.trim();
+    var start = data.indexOf('jsonp(');
+    if (start >= 0) {
+      data = data.substr(start + 6, data.length - start - 6 - 2)
+    }
+    data = JSON.parse(data);
+    success_func(data);
+  }
 
+
+  function getUrlData_xhr(url, success_func, error_func) {
+    jQuery.support.cors = true;
+    jQuery.ajax(url, {
+      headers: { 'X-DataSource-Auth': 'a' },
+      xhrFields: { withCredentials: true },
+      dataType: 'text',
+      success: function(text) { extractJsonFromJsonp(text, success_func); },
+      error: error_func
+    });
+  }
+
+
+  function getUrlData_jsonp(url, success_func, error_func) {
     var iframe = document.createElement('iframe');
     iframe.style.display = 'none';
 
@@ -1747,6 +1768,17 @@
   }
 
 
+  function getUrlData(url, success_func, error_func) {
+    console.debug('fetching data url:', url);
+    var onError = function(xhr, msg) {
+      console.debug('xhr returned error:', msg);
+      console.debug('(trying jsonp instead)');
+      getUrlData_jsonp(url, success_func, error_func);
+    }
+    getUrlData_xhr(url, success_func, onError);
+  }
+
+
   function addUrlGetters(queue, args, startdata) {
     if (!startdata) {
       var url = args.get('url');