我试图通过skiddle API请求事件,使用端点http://www.skiddle.com/api/v1/events/search/,但是当我尝试时,我得到了以下响应:
HTTP/1.1 301 Moved Permanently
Server: CloudFront
Date: Wed, 19 Apr 2023 14:21:19 GMT
Content-Type: text/html
Content-Length: 167
Connection: keep-alive
Location: https://www.skiddle.com/api/v1/events/search/?api_key=xxxxxx&latitude=51.509865&longitude=-0.118092&radius=30&keyword=trance&limit=100&offset=0
X-Cache: Redirect from cloudfront
Via: 1.1 3fff5cbe8229c22a8e7cfe60a8827a1e.cloudfront.net (CloudFront)
X-Amz-Cf-Pop: LHR61-P6
Alt-Svc: h3=":443"; ma=86400
X-Amz-Cf-Id: SLXpElnGSXFF0oD360hjXiwDF2sqfuHD5LggX96rDlUaoHGecskp1Q==
下面是我的代码:
$skiddle = new Skiddle();
$rr = $skiddle->searchEvents('london','trance');
echo $rr->get();
class Locations
{
public static $london = [
'latitude'=>51.509865,
'longitude'=>-0.118092,
'radius'=>30
];
}
class Skiddle
{
const EVENTS_SEARCH_URL = 'http://www.skiddle.com/api/v1/events/search/';
const KEY = "xxxxxxx";
public function __construct(){}
public function searchEvents($location = "", $keyword = "")
{
$params = [
'api_key' => self::KEY
];
if ($location)
{
$params['latitude'] = Locations::$$location['latitude'];
$params['longitude'] = Locations::$$location['longitude'];
$params['radius'] = Locations::$$location['radius'];
}
if ($keyword)
{
$params['keyword'] = $keyword;
}
return new SkiddlePaginatedRequestResponse(
self::EVENTS_SEARCH_URL,
$params
);
}
}
class SkiddlePaginatedRequestResponse extends RequestResponse
{
protected $limit;
protected $offset;
public function __construct($url, $params = [], $limit = 100, $offset = 0)
{
parent::__construct($url, $params);
$this->limit = $limit;
$this->offset = $offset;
}
public function get()
{
return parent::get();
}
public function nextPage()
{
return new SkiddlePaginatedRequestResponse(
$this->url,
$this->params,
$this->limit,
$this->offset + $this->limit
);
}
protected function buildRequest()
{
parent::buildRequest();
$this->request['limit'] = $this->limit;
$this->request['offset'] = $this->offset;
}
protected function handleBadStatus($rawBody, $status, $headers)
{
$errorBody = json_decode($rawBody);
if (isset($errorBody->errormessage) && isset($errorBody->error)) {
// Error from the API
fault("Skiddle error", $errorBody->errormessage."\n".$errorBody->error);
die();
} else {
$this->dieHttpErrorFault($status, $headers);
}
}
}
class RequestResponse
{
protected $params;
protected $url;
protected $request;
protected $cookies = false;
public function __construct($url, $params = [])
{
$this->params = $params;
$this->url = $url;
}
public function setCookies($cookies)
{
//"mycookie1=value1; mycookie2=value2"
$this->cookies = $cookies;
}
public function get()
{
$this->buildRequest();
$url = $this->url . '?' . http_build_query($this->request);
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HEADER => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_URL => $url,
CURLOPT_SSL_VERIFYPEER => false
]);
if ($this->cookies) curl_setopt($ch, CURLOPT_COOKIE, $this->cookies);
$response = curl_exec($ch);
//$rawBody = curl_exec($ch);
if (curl_error($ch))
{
fault('cURL transport error', curl_errno($ch).'\n'.curl_error($ch));
die();
}
list($headers, $rawBody) = explode("\r\n\r\n", $response, 2);
$status = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status < 200 || $status > 299) {
$this->handleBadStatus($rawBody, $status, $headers);
}
$object = json_decode($rawBody, true);
if (json_last_error() !== JSON_ERROR_NONE) {
fault('JSON parsing', "Error ".json_last_error_string()." (".json_last_error().")");
}
return $object;
}
protected function buildRequest()
{
$this->request = $this->params;
}
protected function handleBadStatus($rawBody, $status, $headers)
{
$this->dieHttpErrorFault($status, $headers);
}
protected function dieHttpErrorFault($status, $headers)
{
fault('HTTP error', "Code $status, \nHeaders:\n$headers");
die();
}
}
请指教谢谢
2条答案
按热度按时间5rgfhyps1#
301表示已移动的资源(如果您喜欢,也可以重定向)。可能有几个原因,但我的猜测是,他们重定向您的
http
请求到https
,所以解决方案将只是正确的URL使用https
。或者,你可以像其他人建议的那样设置CURLOPT_FOLLOWLOCATION
,但这不是最佳的,因为你将做两个请求,即使你现在知道第一个是静脉+你的第一个是未加密的。**编辑:**我还注意到
searchEvents()
实现中的一个bug。这些行:我觉得你用的是可变变量(
$$
)。我怀疑是复制-粘贴错误,所以我建议开始使用任何静态linter或至少更智能的IDE:)hgqdbh6s2#
一般来说,使用
CURLOPT_FOLLOWLOCATION
(https://www.php.net/manual/en/function.curl-setopt.php)选项使cURL自动跟随重定向。在您的特定情况下,它似乎只是一个
http://
到https://
协议的重定向,您可以通过直接向https://
版本发出请求来克服它。这将避免每次都提出两个请求。