2016-04-03 27 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(最有可能是前者)的方式相同。 –