0

注: すべてのリンクを投稿するほどの評判はありません。そのため、テキスト エディターがリンクとして読み取らないように、最初の文字を削除しました。それらに移動するには、アドレスバーに貼り付けて、先頭に h を追加してください。

Khan Academy の API を使用してユーザー データにアクセスしようとしていますが、API または AJAX を使用したのはこれが初めてです。これまでのところ、ビデオや演習のデータを取得することはできましたが、OAuth を使用してユーザー データを取得するのに問題があります。カーン アカデミーの承認に関する情報は次のとおりです。OAuth 1.0 を使用します。これが私が使用しているOAuthライブラリです。KA API のドキュメントは次のとおりです: http://api-explorer.khanacademy.org/

var oauth = OAuth({
  consumer: {
    public: '****************',
    secret: '****************'
  },
  signature_method: 'HMAC-SHA1'
});

var request_data = {
  url: 'http://www.khanacademy.org/api/v1/exercises/logarithms_1',
  method: 'GET'
};

$.ajax({
  url: request_data.url,
  type: request_data.method,
  headers: oauth.toHeader(oauth.authorize(request_data))
}).done(function(data) {
  alert("done");
});
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>
  <title>KA API Test</title>
  <meta http-equiv="Access-Control-Allow-Origin" content="*">
  <meta http-equiv="content-type" content="text/html;charset=utf-8" />
  <meta name="generator" content="Geany 1.23.1" />
  <!-- sha1 -->
  <script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/hmac-sha1.js"></script>
  <!-- sha256 -->
  <script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/hmac-sha256.js"></script>

  <script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/enc-base64-min.js"></script>
  <script src="oauth-1.0a.js"></script>
  <script src="jquery-1.12.0.min.js"></script>
</head>

<body>
</body>

</html>

同じHTMLでこのJavascriptも試しました:

var oauth = OAuth({
  consumer: {
    public: 'qdMdMjjJQKrwJw2S',
    secret: '7XeknfpVBzx8fGMK'
  },
  signature_method: 'HMAC-SHA1'
});

var request_data = {
  url: 'http://www.khanacademy.org/api/v1/exercises/logarithms_1',
  method: 'GET'
};

var xhr = new XMLHttpRequest();
xhr.open("GET", "http://www.khanacademy.org/api/v1/exercises/logarithms_1", true);
xhr.setRequestHeader("Authorization", oauth.toHeader(oauth.authorize(request_data)));
xhr.send();
xhr.addEventListener("readystatechange", processRequest, false);

function processRequest(e) {
  if (xhr.readyState == 4 && xhr.status == 200) {
    var response = JSON.parse(xhr.responseText);
    for (var key in response) {
      console.log(key + ":" + response[key]);
    }
    alert(response.translated_description_html);
  }
}

どちらもコンソールに次のエラーを表示します: "XMLHttpRequest cannot load http://www.khanacademy.org/api/v1/exercises/logarithms_1 . Response to preflight request does not pass access control check: No 'Access-Control-Allow- Origin' ヘッダーが要求されたリソースに存在します。Origin ' http://localhost ' へのアクセスは許可されていません。"

注: XMLHttpRequest は正常に動作し、追加xhr.setRequestHeader("Authorization", "OAuth " + oauth.toHeader(oauth.authorize(request_data)));する前に必要なものを返します。ただし、これは認証を必要としない単なるテスト リンクであり、後で変更します。

PSこのエラーを修正したいのですが、OAuthを正しく使用する必要があるだけで、OAuthを使用する前にエラーが発生しなかったため、関連していると思います。

4

1 に答える 1

0

問題は Cross Domain Access Origins にあります。Cross Domains Origin を許可するには、API 所有者に依頼する必要があります。

Access-Control-Allow-Origin is a CORS (Cross-Origin Resource Sharing) header.

サイト A がサイト B からコンテンツをフェッチしようとすると、サイト B は Access-Control-Allow-Origin 応答ヘッダーを送信して、このページのコンテンツが特定のオリジンにアクセス可能であることをブラウザーに伝えることができます。(オリジンは、ドメインにスキームとポート番号を加えたものです。) デフォルトでは、サイト B のページは他のオリジンからはアクセスできません。Access-Control-Allow-Origin ヘッダーを使用すると、特定のオリジン要求によるクロスオリジン アクセスのドアが開きます。

サイト B がサイト A にアクセスできるようにしたいリソース/ページごとに、サイト B はそのページに応答ヘッダーを付けて提供する必要があります。

Access-Control-Allow-Origin: http://siteA.com 最新のブラウザは、クロスドメイン リクエストを完全にブロックしません。サイト A がサイト B からページをリクエストすると、ブラウザは実際にリクエストされたページをネットワーク レベルで取得し、応答ヘッダーにサイト A が許可されたリクエスタ ドメインとしてリストされているかどうかを確認します。サイト B が、サイト A がこのページへのアクセスを許可されていることを示していない場合、ブラウザーは XMLHttpRequest のエラー イベントをトリガーし、要求元の JavaScript コードへの応答データを拒否します。

単純でない要求 ネットワーク レベルで起こることは、上で説明したよりも少し複雑になる可能性があります。リクエストが「単純でない」リクエストである場合、ブラウザは最初にデータのない「プリフライト」OPTIONS リクエストを送信し、サーバーがリクエストを受け入れることを確認します。次のいずれか (または両方) の場合、リクエストは単純ではありません。

GET または POST 以外の HTTP 動詞 (PUT、DELETE など) を使用する単純でない要求ヘッダーを使用する。Accept Accept-Language Content-Language Content-Type (これは、値が application/x-www-form-urlencoded、multipart/form-data、または text/plain の場合にのみ単純です)非単純動詞および/または非単純ヘッダーに一致する適切な応答ヘッダー (非単純ヘッダーの場合は Access-Control-Allow-Headers、非単純動詞の場合は Access-Control-Allow-Methods) で OPTIONS プリフライトに応答します、次にブラウザが実際のリクエストを送信します。

サイト A が /somePage の PUT リクエストを送信する場合、単純ではない Content-Type 値が application/json の場合、ブラウザーは最初にプリフライト リクエストを送信します。

OPTIONS /somePage HTTP/1.1 Origin: http://siteA.com Access-Control-Request-Method: PUT Access-Control-Request-Headers: Content-Type Access-Control-Request-Method と Access-Control-Request に注意してください。 -ヘッダーはブラウザーによって自動的に追加されます。それらを追加する必要はありません。この OPTIONS プリフライトは、成功した応答ヘッダーを取得します。

Access-Control-Allow-Origin: http://  siteA.com

Access-Control-Allow-Methods: GET, POST, PUT

Access-Control-Allow-Headers: Content-Type

実際のリクエストを送信するとき (プリフライトが完了した後)、動作は単純なリクエストの処理方法と同じです。つまり、プリフライトが成功した非単純なリクエストは、単純なリクエストと同じように扱われます (つまり、サーバーは実際の応答のために Access-Control-Allow-Origin を再度送信する必要があります)。

ブラウザーは実際の要求を送信します。

PUT /somePage HTTP/1.1 オリジン: http:// siteA.com コンテンツ タイプ: application/json

{ "myRequestContent": "Response in JSON" } サーバーは、単純なリクエストの場合と同様に、Access-Control-Allow-Origin を返します。

Access-Control-Allow-Origin: http://siteA.com 非単純なリクエストの詳細については、「CORS を介した XMLHttpRequest について」を参照してください。

于 2016-04-03T05:12:19.227 に答える