Сейчас я играю с 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 .