我正在为一个名为Mixi的平台构建一个简单的应用程序,就像日本的Facebook一样。现在,在Javascript API中,我尝试按照给定的API并在传递正确的身份验证令牌后获取用户的配置文件信息。
如果我从浏览器的地址栏触发API链接,则该链接非常有效。但是,经过几个小时的摆弄,尝试JSONP和我能找到的所有可能的变种,Chrome的控制台确实显示数据,但只有当我点击此错误时才会显示:
Uncaught SyntaxError: Unexpected token :
现在,我无法更改服务器端的任何内容,因为它是一个公共API,我需要跨域访问它。如果响应是JSON而不是JSONP,我认为是这样的,可以做些什么来解决?在这种情况下,出路是什么?
我的电话如下:
// token is coming correctly from code above
var reqUrl = "https://api.mixi-platform.com/2/people/@me/@self?access_token=" + token;
$.ajax({
type:'GET',
url: reqUrl,
processData: true,
data: {},
dataType: "jsonp",
success: function (data) {
alert("Success");
alert(data);
},
error: function() { alert("not working..."); },
jsonp: 'jsonp'
});
答案 0 :(得分:2)
除非您请求数据的社交网络启用了CORS(跨源资源共享),否则您无法使用AJAX从它们获取JSON格式的数据,因为它违反了同源策略(SOP)。但是,您可以请求JSONP,跨越原点,因为这不属于SOP裁决,但在查看他们的文档后,他们不提供JSONP格式的响应。
如果您查看其文档的示例代码页here,您将看到支持的语言列表。如果Javascript / jQuery就是其中之一,你会认为他们会给你一个例子。
我认为您需要使用服务器端语言来请求来自它们的数据。我认为你不能使用AJAX。如果您使用的是PHP,则可以使用CURL
或fileGetContents()
。我在下面粘贴了一个PHP示例,可以在GitHub上找到。
PHP示例
<?php
define('CONSUMER_KEY', '[YOUR CONSUMER KEY]');
define('CONSUMER_SECRET', '[YOUR CONSUMER SECRET]');
define('REDIRECT_URI', '[YOUR REDIRECT URI]');
class MixiGraphAPIExample
{
const MIXI_API_ENDPOINT = 'http://api.mixi-platform.com/2';
const MIXI_TOKEN_ENDPOINT = 'https://secure.mixi-platform.com/2/token';
private $token;
public function __construct($auth_code) {
$this->authorize($auth_code);
}
private function post($uri, $data) {
$context = array('http' => array (
'method' => 'POST',
'header' => 'Content-Type: application/x-www-form-urlencoded',
'content' => http_build_query($data, null, '&'),
'ignore_errors' => true,
));
$body = file_get_contents($uri, false, stream_context_create($context));
$header = $this->parseHeader($http_response_header);
if ($this->isHttpFail($header['Status'])) {
throw new UnexpectedValueException('Post Request Fail:'.PHP_EOL.$uri.PHP_EOL.var_export($header, true));
}
return $body;
}
private function authorize($auth_code) {
$data = array(
'grant_type' => 'authorization_code',
'client_id' => CONSUMER_KEY,
'client_secret' => CONSUMER_SECRET,
'code' => $auth_code,
'redirect_uri' => REDIRECT_URI,
);
$this->token = json_decode($this->post(self::MIXI_TOKEN_ENDPOINT, $data), true);
}
private function refreshToken() {
$data = array(
'grant_type' => 'refresh_token',
'client_id' => CONSUMER_KEY,
'client_secret' => CONSUMER_SECRET,
'refresh_token' => $this->token['refresh_token'],
);
$this->token = json_decode($this->post(self::MIXI_TOKEN_ENDPOINT, $data), true);
}
private function parseHeader($headers) {
$statusLine = array_shift($headers);
list(, $result['Status'], ) = explode(' ', $statusLine);
foreach ($headers as $header) {
list($key, $value) = explode(': ', $header);
$result[$key] = $value;
}
return $result;
}
private function isHttpFail($status) {
return (bool)(empty($status) || ($status >= 400));
}
private function isExpired($headers) {
$result = false;
if (array_key_exists('WWW-Authenticate', $headers)) {
if (preg_match('/expired_token/', $headers['WWW-Authenticate'])) {
$result = true;
}
}
return $result;
}
private function call($location) {
static $retry_count = 0;
$uri = self::MIXI_API_ENDPOINT . $location . '?oauth_token=' . $this->token['access_token'];
$response = file_get_contents($uri, false, stream_context_create(array('http' => array('ignore_errors' => true))));
$header = $this->parseHeader($http_response_header);
if ($this->isHttpFail($header['Status'])) {
if ($this->isExpired($header)) {
if ($retry_count++ > 1) {
throw new RangeException('Token Refresh Too many retry. '.PHP_EOL.var_export($this->token, true).PHP_EOL.var_export($header, true));
}
$this->refreshToken();
$response = $this->call($location);
$retry_count = 0;
} else {
throw new UnexpectedValueException('Invalid API Access:'.PHP_EOL.$uri.PHP_EOL.var_export($header, true));
}
}
return $response;
}
public function execute($endpoint) {
return json_decode($this->call($endpoint), true);
}
public static function getInstance($auth_code) {
return new self($auth_code);
}
}
if (debug_backtrace()) return;
if ($_SERVER['argc'] != 2) {
exit("Please input your Authorization Code\n Usage : {$_SERVER['argv'][0]} [YOUR AUTHORIZATION CODE]\n");
}
try {
$response = \MixiGraphAPIExample::getInstance($_SERVER['argv'][1])->execute('/people/@me/@self');
var_dump($response);
} catch (Exception $e) {
var_dump($e->getMessage());
}