Сейчас я играю с Backbone и использую публичный API в качестве источника. Веб-браузер имеет одну ужасную особенность: он не позволяет вам извлекать какие-либо внешние ресурсы на наш хост из-за ограничений на разные источники. Например, если у нас есть сервер на локальном хосте, мы не можем выполнить один AJAX-запрос к другому хосту, отличному от локального хоста. В настоящее время есть заголовок, позволяющий это сделать:
Access-Control-Allow-Origin, Проблема в том, что удаленный сервер должен настроить этот заголовок. Например, я играл с API GitHub, и у GitHub нет этого заголовка. Если сервер является моим сервером, довольно просто поместить этот заголовок, но, очевидно, я не являюсь системным администратором github, поэтому я не могу этого сделать. Какое решение? Одним из возможных решений является, например, создание прокси-сервера на локальном хосте с PHP. С PHP мы можем использовать любой удаленный API с curl (я писал об этом
здесь и
здесьнапример). Это не сложно, но я спросил себя: можем ли мы создать фиктивный прокси-сервер с PHP для обработки любого запроса на локальный хост и перенаправления на реальный сервер, вместо того, чтобы создавать один прокси для каждого запроса? Давайте начнем. Вероятно, есть одно решение с открытым исходным кодом (скажите, знаете ли вы его), но я нахожусь в отпуске, и я хочу немного кодировать (я сейчас, это выглядит безумно, но это я
).Идея заключается в следующем:
...
$proxy->register('github', 'https://api.github.com');
...
И когда я печатаю:
HTTP: // локальный / GitHub / пользователей / gonzalo123
и создайте прокси для:
https://api.github.com/users/gonzalo123
Метод запроса также важен. Если мы создаем POST-запрос к localhost, мы хотим, чтобы POST-запрос также выполнялся на github.
На этот раз мы не собираемся изобретать велосипед, поэтому мы будем использовать symfony componets, поэтому мы будем использовать composer для запуска нашего проекта:
Мы создаем файл conposer.json с зависимостями:
{
"require": {
"symfony/class-loader":"dev-master",
"symfony/http-foundation":"dev-master"
}
}
Теперь
php composer.phar install
И мы можем начать кодирование. Сценарий будет выглядеть так:
register('github', 'https://api.github.com');
$proxy->run();
foreach($proxy->getHeaders() as $header) {
header($header);
}
echo $proxy->getContent();
Как мы видим, мы можем зарегистрировать столько серверов, сколько захотим. В этом примере мы регистрируем только github. Приложение имеет только два класса:
RestProxy , который извлекает информацию из объекта запроса и обращается к реальному серверу через CurlWrapper .
<?php
namespace RestProxy;
class RestProxy
{
private $request;
private $curl;
private $map;
private $content;
private $headers;
public function __construct(\Symfony\Component\HttpFoundation\Request $request, CurlWrapper $curl)
{
$this->request = $request;
$this->curl = $curl;
}
public function register($name, $url)
{
$this->map[$name] = $url;
}
public function run()
{
foreach ($this->map as $name => $mapUrl) {
return $this->dispatch($name, $mapUrl);
}
}
private function dispatch($name, $mapUrl)
{
$url = $this->request->getPathInfo();
if (strpos($url, $name) == 1) {
$url = $mapUrl . str_replace("/{$name}", NULL, $url);
$queryString = $this->request->getQueryString();
switch ($this->request->getMethod()) {
case 'GET':
$this->content = $this->curl->doGet($url, $queryString);
break;
case 'POST':
$this->content = $this->curl->doPost($url, $queryString);
break;
case 'DELETE':
$this->content = $this->curl->doDelete($url, $queryString);
break;
case 'PUT':
$this->content = $this->curl->doPut($url, $queryString);
break;
}
$this->headers = $this->curl->getHeaders();
}
}
public function getHeaders()
{
return $this->headers;
}
public function getContent()
{
return $this->content;
}
}
RestProxy получает два экземпляра в конструкторе через внедрение зависимостей (CurlWrapper и Request). Эта архитектура очень помогает в тестах , потому что мы можем высмеивать оба экземпляра. Очень полезно при сборке RestProxy.
RestProxy зарегистрирован в packaist, поэтому мы можем установить его с помощью установщика composer:
Сначала установите компонент
curl -s https://getcomposer.org/installer | PHP
и создайте новый проект:
php composer.phar create-project gonzalo123 / rest-proxy proxy
Если мы используем PHP5.4 (если нет, чего вы ждете?), Мы можем запустить встроенный сервер
cd proxy php -S localhost:8888 -t www/
Теперь нам нужно только открыть веб-браузер и набрать:
http://localhost:8888/github/users/gonzalo123
Библиотека очень минимальна (этого достаточно для моего эксперимента) и не допускает авторизацию.
Конечно, полный код доступен в github .