2016-04-03 28 views
0

注意:我沒有足夠的聲望發佈所有鏈接,因此我只刪除了第一個字母,以便文本編輯器不會將其作爲鏈接閱讀。要去他們,請將其粘貼到您的地址欄,並在前面添加h。如何使用JavaScript與OAuth訪問可汗學院API?

我想從可汗學院使用他們的API訪問用戶數據,但是,這是我第一次使用他們的API或AJAX。到目前爲止,我已經設法檢索視頻或練習的數據,但我在使用OAuth檢索用戶數據時遇到了問題。這裏是info on Khan Academy authorization。他們使用OAuth 1.0。這裏是the OAuth library I am using。下面是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" 
 
\t "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>

我自己也嘗試此Javascript使用相同的HTML:

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無法加載http://www.khanacademy.org/api/v1/exercises/logarithms_1。對預檢請求的響應不會通過訪問控制檢查:請求的資源上不存在「訪問控制 - 允許來源」標頭。 「http://localhost」因此不允許訪問。「

注意:XMLHttpRequest正常工作並返回我想要的內容,然後添加xhr.setRequestHeader("Authorization", "OAuth " + oauth.toHeader(oauth.authorize(request_data)));。但是,這只是一個不需要授權的測試鏈接,我會更改它後來,

PS我想解決這個錯誤,但我也只需要正確使用OAuth,我想是因爲我沒有使用OAuth之前有錯誤,他們是相關的。

回答

0

的問題是具有跨域訪問起源您需要向API所有者請求允許跨域名稱起源

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

當站點A嘗試獲取來自站點B的內容,站點B可以發送訪問控制允許來源響應頭告訴瀏覽器,這個頁面的內容是一定的淵源訪問。 (源是域,加上方案和端口號。)默認情況下,站點B的頁面不能被任何其他來源訪問;使用Access-Control-Allow-Origin標題爲特定請求源的跨源訪問打開了一扇門。

對於每個資源/頁站點B要做出一個網站訪問,站點B應該成爲它與響應報頭頁:

訪問控制允許來源:HTTP:// siteA.com 現代瀏覽器不會完全阻止跨域請求。如果站點A從站點B請求一個頁面,瀏覽器將實際獲取網絡級別上請求的頁面,並檢查響應標題是否將站點A列爲允許的請求者域。如果站點B未指示站點A被允許訪問此頁面,瀏覽器將觸發XMLHttpRequest的錯誤事件,並拒絕對發出請求的JavaScript代碼的響應數據。

非簡單請求 在網絡級別發生的情況可能比上面解釋的稍微複雜一些。如果請求是「非簡單」請求,則瀏覽器首先發送無數據「預檢」OPTIONS請求,以驗證服務器是否接受請求。當(或兩者之一)請求是非簡單的:

使用非GET或POST(例如PUT,DELETE)的HTTP動詞 使用非簡單請求頭;只有簡單的請求標頭是: 接受 接受語言 內容 - 語言 內容類型(這只是簡單的時候它的值是application/x-www-form-urlencoded,multipart/form-data或text/plain ) 如果服務器使用適當的響應標頭(適用於非簡單標頭的Access-Control-Allow-Headers,用於非簡單動詞的Access-Control-Allow-Methods)響應OPTIONS預檢,並匹配非簡單動詞和/或非簡單的標題,然後瀏覽器發送實際的請求。

假設站點A要發送的/ SomePage的PUT請求,與應用/ JSON的非簡單的內容類型值,瀏覽器將首先發送一個預檢要求:

選項/ SomePage的HTTP/1.1 來源:http://siteA.com 訪問控制請求方法:PUT 訪問控制請求頭:內容類型 請注意,訪問控制請求方法和訪問控制請求頭是由瀏覽器添加的自動;你不需要添加它們。這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 內容類型:應用/ JSON

{ 「myRequestContent」:「響應在JSON」} 而服務器返回一個訪問控制允許來源,就像它爲一個簡單的要求:

訪問控制允許來源:HTTP:// siteA.com 請參閱瞭解關於CORS的XMLHttpRequest瞭解更多信息非簡單的請求。

+0

並允許每一個地方,你可以使用: '訪問控制允許來源:*' 作爲通配符項 –

+0

您可以瞭解從以下網址更多: https://developer.mozilla.org/en -US/docs/Web/HTTP/Access_control_CORS –

+0

因此,如果問題是Khan Academy不允許跨源請求,那麼爲什麼程序在添加身份驗證之前工作?這個問題必須與我使用的方式或可汗學院設置OAuth(最有可能是前者)的方式相同。 –