14

I'm experiencing the same/similar problem as described in API has been failing with CORS errors since 11/13

When I run the below stack-snippet that basically makes various calls to the SE API, I'm greeted with a CORS error once I run into the throttle limit of I think the HA-proxy. I'm happy to handle the throttle and back-off a lot but it would help if I could get the real HTTP error code.

Access to XMLHttpRequest at 'https://api.stackexchange.com/2.2/users...' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

For those who want to reproduce this, the included code-snippet can be run while you watch the Developer Console. WARNING: This code will IP address throttle your connection to the SE network so if you run it and hit the throttle, you might not be able to post for a few minutes

Can this be looked at and if possible be fixed so the proper headers are sent for https://api.stackexchange.com/2.x/ routes despite being in a throttled error condition?


I do know this code doesn't honor the backoff parameter but trust me, in the actual code I do handle backoff and that isn't enough to always steer clear from this error. In this sense this is a minimal, complete, verifiable example. Not a sane example.

var api = {
  url: 'https://api.stackexchange.com/2.2/',
  endpoint: 'questions/featured',
  params: {
    site: 'stackoverflow',
    pagesize: 100,
    order: 'desc',
    sort: 'activity',
    Filter: '!iCF4LsDYJt6oT_Y1qKBCOv',
    key: 'VyQN2SnsdXDfeiBS9*ZsEg(('
    }
  };

function createUrl(ap) {
  var ep = ap.url + ap.endpoint +'?',
     nv = [];
  if (ap.params) {
    for(var p in ap.params) {
      if (ap.params.hasOwnProperty(p)) {
           nv.push(p + '=' + ap.params[p]);
      }
    }
  }
  // console.log(ep + nv.join('&'));
  return ep + nv.join('&');
}

function createSitesUrl() {
  return createUrl(
    { url: api.url,
      endpoint: 'sites',
      params: {
        pagesize: 500,
        key: api.params.key,
        filter: '!*l7_tSmzy1mF3bw9odQw*8ur' }
     });
}

function createUserFeaturedUrl(userid, site) {
  return createUrl(
    { url: api.url,
      endpoint: 'users/'+ userid + '/questions/featured',
      params: {
        site: site,
        pagesize: 100,
        key: api.params.key,
        filter: '!*7PmgCF3rY3WihzNKHz4jURFN9X6' }
     });
}

function createInfoUrl(site) {
  return createUrl(
    { url: api.url,
      endpoint: 'info',
      params: {
        site: site,
        key: api.params.key,
        filter: '!39qVOEzAjeqnKS5bl7_puf_.GSZJG' }
     });
}

function createAccountsUrl(accountid) {
  return createUrl(
    { url: api.url,
      endpoint: 'users/'+ accountid + '/associated',
      params: {
        pagesize: 100,
        key: api.params.key,
        filter: '!w*vp4lVBIX453e.b5Y' }
     });
}

// used when we are good to call
function get(url, callback) {
   var xhr = new XMLHttpRequest();
   xhr.open('GET', url);
   xhr.addEventListener('load', function() {
     var data;
     if (xhr.readyState === 4 && xhr.status === 200) {
       data = JSON.parse(xhr.responseText);
       callback(data);
     } else {
       console.log('readystate and status ', xhr.readyState, xhr.status);
     }
  });

  xhr.addEventListener('error', function(err) {
    console.log('error for ', url, err, xhr.status);
    document.getElementById('err').textContent=xhr.status + xhr.statusText;
    console.log('error after nasty error ', err);
  });

  xhr.addEventListener('abort', function() {
    console.log('abort for ', url, xhr.status);
  });
  xhr.send();
}

function loadUserFeatured(userid, site) {
   console.log('loadUserFeatured', userid, site);
   get(createUserFeaturedUrl(userid, site.api_site_parameter), function(data) {
     data.items.forEach( function(item) {
         console.log(item);
     });
  });
}


function loadUserFromAccount(item) {
  console.log('loadUserFromAccount', item);
  var uid = item.user_id;
  var site = item.site_url.replace('https://','');
  get(createInfoUrl(site), function(data) {
    loadUserFeatured(uid, data.items[0].site);
  });
}

function loadAccounts(accountId) {
  console.log('loadAccounts', accountId);
  get(createAccountsUrl(accountId), function(data) {
    data.items.forEach( function(item) {
       loadUserFromAccount(item);
    });
  });
}

loadAccounts(267077);  // network profile with lots of accounts
Caution! When you run this you will flood the SE servers with many, many calls. They might hate you. So much, you'll be IP blocked.
<div id='err'></div>

You must log in to answer this question.

Browse other questions tagged .