javascript - GitHub API CORS 政策

标签 javascript cors github-api

我正在使用 jQuery 和 ajax 向 GitHub API 发出 get 请求,但刷新大约 3 次后,请求开始失败,并显示:

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

尽管如此,我已将我的域注册为 GitHub OAuth 应用程序。

这是我的 JavaScript:

let repos = [];
const isEnglish = document.documentElement.lang == 'en';
class Repo {
  constructor(name, description, webUrl, apiUrl) {
    this._name = name;
    this._description = description;
    this._webUrl = webUrl;
    this._apiUrl = apiUrl;
    this._languages = [];
    this.fetchLanguages();
  }

  get name() {
    return this._name;
  }

  get description() {
    return this._description;
  }

  get url() {
    return this._webUrl;
  }

  get languages() {
    return this._languages;
  }

  set languages(value) {
    this._languages = value;
  }

  async fetchLanguages() {
    const url = this._apiUrl + '/languages';
    await $.ajax({
      url: url,
      complete: data => {
        this._languages = Object.keys(data.responseJSON);
      },
    });
  }
}

$(document).ready(async () => {
  $.ajax({
    url: 'https://api.github.com/users/X/repos',
    complete: xhr => {
      repos = xhr.responseJSON.map(json => {
        return new Repo(json.name, json.description, json.html_url, json.url);
      });
      // build up list based on data
      const container = document.getElementById('projectListContainer');
      repos.forEach(repo => {
        const li = document.createElement('li');

        //header
        const collapsibleHeader = document.createElement('div');
        collapsibleHeader.classList.add('collapsible-header');
        const headerText = document.createTextNode(repo.name);
        collapsibleHeader.appendChild(headerText);
        li.appendChild(collapsibleHeader);

        //body
        const collapsibleBody = document.createElement('div');
        collapsibleBody.classList.add('collapsible-body');

        const description = document.createElement('p');
        const descText = document.createTextNode(repo.description);
        description.appendChild(descText);
        collapsibleBody.appendChild(description);

        const languages = document.createElement('p');
        languages.style.marginTop = '1rem';
        const langTxt = isEnglish ? 'Languages used: ' : 'Talen gebruikt: ';
        const langText = document.createTextNode(langTxt + repo.languages);
        languages.appendChild(langText);
        collapsibleBody.appendChild(languages);

        const url = document.createElement('a');
        url.href = repo.url;
        url.target = '_blank';
        url.style.marginTop = '1rem';
        url.style.display = 'block';
        url.style.fontSize = '12px';
        const urlText = document.createTextNode(repo.url);
        url.appendChild(urlText);
        collapsibleBody.appendChild(url);

        li.appendChild(collapsibleBody);
        container.appendChild(li);
      });
    },
    error: () => {
      const container = document.getElementById('projectListContainer');
      const div = document.createElement('div');
      div.classList.add('center');
      const txt = isEnglish
        ? 'Something went wrong or the request limit is reached, check back later!'
        : 'Er is iets fout gegeaan of het maximum aantal requests is bereikt, kom later terug!';
      const text = document.createTextNode(txt);
      div.appendChild(text);
      container.appendChild(div);
    },
  });
  updateTable();
});

const updateTable = () => {
  repos.forEach(repo => {
    const tdLanguages = document.getElementsByClassName(`${repo.name}Lang`)[0];
    tdLanguages.innerHTML = repo.languages.join(', ');
  });
};

最佳答案

对于未经身份验证的请求,他们每小时最多限制 60 个请求。您可以通过验证 API 请求将其增加到每小时 5000 个。

所以,当我几周前遇到这个问题时,我在 gihub 创建了 personal_auth_token 并在 headers 中传递了这个 token ,问题就解决了。

要生成 personal_auth_token,请登录 github.com转至设置 -> 开发人员设置 -> 个人访问 token 并生成一个。

将此 token 传递到 Auhtorization: *token* 下的 headers 中。因此,在您的 AJAX 请求中,它可能如下所示:

$.ajax({
    url: *yourUrl*
    ...
    beforeSend: function (xhr) {
        xhr.setRequestHeader('Authorization', *token*));
    },
});

这里需要注意的一件事是,如果存储库是公共(public)的,不要使用此 token 在 github 上推送代码。这会立即被检测到, token 将被撤销,您需要再次创建一个。

For API requests using Basic Authentication or OAuth, you can make up to 5000 requests per hour. Authenticated requests are associated with the authenticated user, regardless of whether Basic Authentication or an OAuth token was used. This means that all OAuth applications authorized by a user share the same quota of 5000 requests per hour when they authenticate with different tokens owned by the same user.

For unauthenticated requests, the rate limit allows for up to 60 requests per hour. Unauthenticated requests are associated with the originating IP address, and not the user making requests.

https://developer.github.com/v3/#rate-limiting

在我的案例中有效的另一个解决方案是使用代理服务器解决 CORS 问题。在此情况下,您只需将 API 请求 URL 附加到代理服务提供商,例如 https://cors-anywhere.herokuapp.com/

var url = "http://example.com/repo"; //your api request url,
var proxyUrl = `https://cors-anywhere.herokuapp.com/${url}`;

fetch(proxyUrl)... //Make a request with this proxy url to navigate CORS issue

关于javascript - GitHub API CORS 政策,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62298627/

相关文章:

javascript - ($ ('.class-name' ).is (":checked")) 从来不为真

javascript - 将 jQuery 单击事件绑定(bind)到常规 javascript 按钮

javascript - 具有色相/饱和度和更多控件的随机颜色生成器

javascript - 在Vue客户端和服务器应用程序中如何消除对CORS的需要?

Javascript:编辑列表项

http - 允许任何 CORS 源 (*) 时是否应设置 'Vary: Origin'?

javascript - backbone.js 和 CORS

python - 如何在 Python 中实现 curl -u?

ruby-on-rails - GitHub API : Cannot reliably add files to repository

github - 如何获得所有超过 20 颗星的公共(public) GitHub 存储库的列表?