Кроссдоменый запрос - это запрос ресурса со стороннего домена.
Обычно запрос XMLHttpRequest может делать запрос только в рамках текущего сайта. При попытке использовать другой домен/порт/протокол – браузер выдаёт ошибку.
Правило ограничения домена (Same Origin Pliicy, «Принцип одинакового источника») - это важная концепция безопасности на стороне клиента, для языка программирования JavaScript. Политика разрешает сценариям, находящимся на страницах одного сайта, доступ к методам и свойствам друг друга без ограничений, но предотвращает доступ к большинству методов и свойств для страниц на разных сайтах.
Одинаковые источники - это источники, у которых совпадают три признака:
домен
порт
протокол
Концепция правила ограничения домена появилась во времена Netscape Navigator 2.0.
Для иллюстрации данного правила посмотрим на следующую таблицу, которая даёт обзор типичных проверок. К примеру, запрос производится со следующего URL http://www.example.com/dir/page.html.
Явное указание порта. Зависит от реализации в браузере.
Существует современный стандарт который предусматривает кроссдоменные запросы и многое другое. Большинство возможностей этого стандарта уже поддерживаются всеми современными браузерами.
Cross-origin resource sharing (CORS «совместное использование ресурсов между разными источниками») - технология современных браузеров, которая позволяет предоставить веб-странице доступ к ресурсам другого домена. w3c CORS
Идея проста – пусть клиент шлет AJAX-запрос к чужому серверу. Браузер добавит в запрос особые заголовки с информацией о том, что запрос с другого домена. На их основании сервер решит, как обрабатывать такой запрос, и добавит особые заголовки в ответ.
Техническая реализация несколько сложнее. Спецификация CORS налагает специальные ограничения на запросы. Запросы в ней делятся на два вида: “простые” и “сложные”.
Простыми считаются запросы, если они удовлетворяют следующим двум условиям:
Простой метод: GET, POST или HEADПростые заголовки – только из списка:
Accept
Accept-Language
Content-Language
Content-Type со значением application/x-www-form-urlencoded, multipart/form-data или text/plain.
«Непростыми» считаются все остальные, например, запрос с методом PUT или с заголовком Authorization не подходит под ограничения выше.
Принципиальная разница между ними заключается в том, что «простой» запрос можно сформировать и отправить на сервер и без XMLHttpRequest, например при помощи HTML-формы.
Если ваш запрос удовлетворяет этим критериям, можно слать AJAX запрос к другому домену из любого современного браузера. При этом браузер добавит заголовок Origin с адресом страницы, откуда инициирован запрос. Подделать заголовок скриптом не удастся.
В кросс-доменный запрос браузер автоматически добавляет заголовок Origin, содержащий домен, с которого осуществлён запрос.
Сервер, получив на обработку подобный запрос, должен прочесть Origin и решить, как его обрабатывать. Заголовок ответа Access-Control-Allow-Origin регулирует, с какого домена разрешено запрашивать данные. Это может быть как веб-адрес, так и знак "звездочки", если разрешено всем.
Несколько разных адресов через запятую, к сожалению, не поддерживаются для заголовка Access-Control-Allow-Origin
В случае запроса на http://foo.com/folderimg с http://mysite.ru/page заголовки будут примерно такие:
GET /folderimg
Host: foo.com
Origin: http://mysite.ru
Сервер должен, со своей стороны, ответить специальными заголовками, разрешает ли он такой запрос к себе.
Если сервер разрешает кросс-доменный запрос с этого домена – он должен добавить к ответу заголовок Access-Control-Allow-Origin, содержащий домен запроса (в данном случае «mysite.ru») или звёздочку *.
200 OK HTTP/1.1
Access-Control-Allow-Origin: http://mysite.ru
Content-Type: text/html; charset=utf-8
<h1>Welldone</h1>
Только при наличии такого заголовка в ответе – браузер сочтёт запрос успешным, а иначе JavaScript получит ошибку.
Если Access-Control-Allow-Origin нет, то браузер считает, что разрешение не получено, и завершает запрос с ошибкой.
При таких запросах не передаются куки и заголовки HTTP-авторизации.
В кросс-доменном XMLHttpRequest можно указать не только GET/POST, но и любой другой метод, например PUT, DELETE.
Когда-то никто и не думал, что страница сможет сделать такие запросы. Поэтому ряд веб-сервисов написаны в предположении, что «если метод – нестандартный, то это не браузер». Некоторые веб-сервисы даже учитывают это при проверке прав доступа.
Чтобы пресечь любые недопонимания, браузер использует предзапрос в случаях, когда:
Если метод – не GET / POST / HEAD.
Если заголовок Content-Type имеет значение отличное от application/x-www-form-urlencoded, multipart/form-data или text/plain, например application/xml.
Если устанавливаются другие HTTP-заголовки, кроме Accept, Accept-Language, Content-Language.
Любое из условий выше ведёт к тому, что браузер сделает два HTTP-запроса.
Первый запрос называется «предзапрос» (английский термин «preflight»). Браузер делает его целиком по своей инициативе, из JavaScript мы о нём ничего не знаем, хотя можем увидеть в инструментах разработчика.
Этот запрос использует метод OPTIONS. Он не содержит тела и содержит название желаемого метода в заголовке Access-Control-Request-Method, а если добавлены особые заголовки, то и их тоже – в Access-Control-Request-Headers.
Его задача – спросить сервер, разрешает ли он использовать выбранный метод и заголовки.
На этот запрос сервер должен ответить статусом 200, без тела ответа, указав заголовки Access-Control-Allow-Method: метод и, при необходимости, Access-Control-Allow-Headers: разрешённые заголовки.
Дополнительно он может указать Access-Control-Max-Age: sec, где sec – количество секунд, на которые нужно закэшировать разрешение. Тогда при последующих вызовах метода браузер уже не будет делать предзапрос.
Пример сложного запроса →(см. папку example/)
cURL
cURL - (распространяемая по лицензии MIT), кроссплатформенная служебная программа командной строки, позволяющая взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
С приходом обновления Redstone 4 «April 2018 Update» (версия 1803) для Windows 10, программа cURL была включена в состав этой операционной системы.
Программа cURL может автоматизировать передачу файлов или последовательность таких операций. Например, это хорошее средство для моделирования действий пользователя в веб-обозревателе.
Программа поддерживает протоколы: FTP, FTPS, HTTP, HTTPS, TFTP, SCP, SFTP, Telnet, DICT, LDAP, а также POP3, IMAP и SMTP. Также cURL поддерживает сертификаты HTTPS, методы HTTP POST, HTTP PUT, загрузку на FTP, загрузку через формы HTTP.
Поддерживаемые методы аутентификации: базовая, дайджест, NTLM и Negotiate для HTTP, а также Kerberos для FTP.
Возможно возобновление передачи файла с места обрыва (при поддержке протоколом), туннелирование через HTTP-прокси, поддержка HTTP-Cookie.
Первоначально cURL разработан как средство перемещения файлов между конечными точками с использованием различных протоколов, таких как FTP, HTTP, SCP и другие. Сначала это была утилита командной строки, но теперь это также библиотека с привязками более чем к 30 языкам. Так что теперь, вместо того чтобы использовать cURL из командной строки, можно создавать приложения, которые включают в себя эти важные функции. Библиотека libcurl также переносима и поддерживает Linux, IBM AIX, BSD, Solaris и многие другие варианты UNIX.
Ниже будут представлены далеко не все параметры и возможности cURL, но они дают понять, что это больше чем просто утилита командной строки для Linux или Windows. Это набор библиотек, в которых реализуются базовые возможности работы с URL страницами и передачи файлов. Библиотека поддерживает работу с большим количеством протоколов. Она отлично подходит для имитации действий пользователя на страницах и других операций с URL адресами.
Проверка URL
Одним из наиболее распространенных и простейших применений cURL - это проверка состояния по текущему URL.
curl https://zamt.000webhostapp.com/
Эта команда будет отображать содержимое URL на вашем терминале.
Сохранение вывода
Выход команды cURL может легко сохранить в файл, добавив опцию -o и указав имя файла под которым сохраниться вывод
Не всегда нам обязательно нужно содержимое страницы. Иногда могут быть интересны только заголовки. Чтобы вывести только их есть опция -I
curl -I https://zamt.000webhostapp.com/
Аутентификация
Если на сервере требуется аутентификация одного из распространенных типов, например, SSH или FTP, то curl очень просто может справиться с такой задачей. Для указания данных аутентификации просто укажите их через двоеточие в опции -u
curl -u electro:electro ftp://ftp.ntsomz.ru/
В данном примере мы получим список файлов и каталогов по текущему адресу. Обратите внимание, если Вам необходимо загрузить файл, то Вы должны использовать полный путь к файлу(не забываем про опцию -O).
-С или --continue-at <offset> используется для продолжения работы предыдущей сессии передачи файлов с заданным смещением. При использовании FTP сервера команда SIZE не будет использована curl. Можно использовать "-C -", чтобы curl автоматически нашал место где возобновить передачу.
Так же можно воспользоваться опцией -#, которая отображает простой прогресс-бар во время загрузки заместо таблицы.
--limit-rate <speed> - опция задает максимальную скорость передачи данных. Этот параметр полезен, если у вас ограниченный канал и Вы не хотите его перегружать.
Скорость канала измеряется в байтах в секунду, если не использовать суффикс. Буквы 'k' или 'K' означают килобайт в секунду, 'm' или 'M' -мегабайт в секунду и 'g' или 'G' гигабайт в секунду. Например : 100K, 3m, 1G
Чтобы данные примеры работали в стенах техникума необходимо дополнительно использовать опцию --proxy <[protocol://][user@password]proxyhost[:port]>, которая указывает прокси сервер.
libcurl — это библиотека API для передачи, которую разработчики могут встроить в свои программы; cURL действует как автономная обёртка для библиотеки libcurl. libcurl используется, чтобы обеспечить возможность передачи файлов (адресуемых с помощью URL) многочисленным приложениям (как открытым, так и коммерческим).
PHP включена поддержка libcurl - библиотеки функций, которая позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов. В настоящее время libcurl поддерживает протоколы http, https, ftp, gopher, telnet, dict, file и ldap. libcurl также умеет работать с сертификатами HTTPS, посылать запросы к HTTP серверам методами POST и PUT, закачивать файлы по протоколам HTTP и FTP.
Работа с cURL всегда начинается с
вызова curl_init(), затем
устанавливаются необходимые параметры с помощью curl_setopt(), и
выполняется требуемая операция вызовом curl_exec(), после чего
вызовом curl_close() сеанс работы завершается.
Самый простой пример использования libcurl в PHP
$url = "https://ya.ru";
/* инициализация сеанса с последующим возвращением дескриптора,
который используется с функциями */
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url); //
/* Загружаемый URL. Данный параметр может быть также установлен
при инициализации сеанса с помощью curl_init(). */
//$ch = curl_init($url);
curl_exec($ch); // выполнить операцию
curl_close($ch); // закрытие сеанса
В результате на станице отобразиться содержимое по адресу "https://ya.ru". cURL. Пример 1
Прямой вывод результата работы в браузер не всегда полезене и для того чтобы результат возвращался в качестве строки из curl_exec() используется параметр CURLOPT_RETURNTRANSFER