Pull to refresh

Кроссдоменный AJAX-запрос для Opera.

Lumber room
Известно, что XmlHttpRequest в Opera срабатывает только в том домене, где открыт яваскрипт. Ниже я приведу способ, как миновать эту оплошность.

Отправляем данные и получаем результат — картинку


Для отправки информации на другой хост вместо XmlHttpRequest я использую простой DOM, создающий картинку, загружающую серверный скрипт с другого домена. Результатом может быть получено изображение. Вот пример скрипта, который только отсылает данные на сторонний сервер:

//тест первый
function postDataImage(addr) {
  //создаём новую картинку 
  var img = document.createElement("img");
  img.src = addr;
  //если мы хотим сделать результат видимым пользователю, 
  //то эту картинку подключаем в документ
  document.getElementById("result").appendChild(img);
}

//осуществляем "подобие" ajax-запроса таким образом
postDataImage("http://your.domain.com/serverside.image.php");

Как результат мы получили картинку, ею например можно заменить ту, которую «кликнули». Если наша задача только отослать данные, то картинку вовсе можно не подключать к document. А как же быть с другими результатами?

Если результат — число


Как уже сказано выше с картинками в Opera нет проблем, они запрашиваются с любого домена. Только нам изображений не достаточно, нам числа подавай (например ID-пользователя). С небольшими числами пожалуй можно разрулить. Взять например размер картинки которую мы получили от сервера: ширина*256+высота даст нам возможность отобразить числа от 0 до 65535 или от -32767 до 32767. JPEG-картинка такого размера не будет слишком много весить.

Вот пример, скрипт отвечает Success! когда полученная от сервера картинка имеет ширину 290 пикс.

//тест второй
function postDataImageAndProcess(addr) {
  //показываем сообщение Loading...
  document.getElementById("result").innerHTML = "Loading ...";
  //создаём картинку
  var img = document.createElement("img");
  img.src = addr;
  //ставим триггер когда картинка загрузится
  img.onload = function () {
    //когда картинка загружена, проверяем её ширину
    //если 290 пикселей, значит всё верно
    var result = (this.width == 290) ? 
          "Success, image width 290px!" : 
          "Other result! Image width is not 290px";
    document.getElementById("result").innerHTML = result;
  }  
}

//осуществляем "подобие" ajax-запроса таким образом
postDataImageAndProcess("http://your.domain.com/serverside.image.php");

Это, господа, я описываю эволюцию инженерной мысли, как она у меня созревала. И вот, я добрался до самого интересного. Как же всё-таки сделать нормальный запрос к серверу и получить нормальный от него ответ: текст, или массив данных, или ещё что-нибудь? Хотел задать я вам этот вопрос, а впрочем, покумекал и дописал статейку сам (оказывается думать полезно ;)

Наконец, полноценный запрос/ответ


Вспоминаем, у каких ещё тегов имеется параметр src? <script&gt! И начинаем мутить процедуру:

//тест третий
function postDataScript(addr) {
  //показываем сообщение Loading...
  document.getElementById("result").innerHTML = "Loading ...";
  //создаём объект
  var awesome = document.createElement("script");
  awesome.src = addr;
  document.getElementsByTagName("head")[0].appendChild(awesome);
}

//осуществляем "подобие" ajax-запроса таким образом
postDataImageAndProcess("http://your.domain.com/serverside.javascript.php");

serverside.javascript.php содержит header('Content-type: text/javascript'); и конечно же все атрибуты, чтобы результаты не кешировались, а в теле будет прописан javascript. Для примера я поставил строчку, изменяющую содержимое ячейки result в нашем документе:

document.getElementById("result").innerHTML = "Yes, it works";

Вот и всё. Самый получился что ни есть, AJAX.

Уточняю, что все действия проводились для Opera 9.61, а предмет изучения — кроссдоменные AJAX запросы, которые стандартно в Опере запрещены. Данная тема ещё далеко не исчерпана, тут ещё есть над чем подумать:
— Создать библиотеку с набором функций, как MSXMLHTTP, только для кроссдоменных запросов.
— Научить Opera таким же образом делать запросы с методом POST (возможно ли это? думаю что посредством форм)
— Предлагайте… ;)

Рабочий пример лежит тут: www.blackcrystal.net/labs/operacrossdomainrequest/test.html
Серверные скрипты для теста тут: www.blackcrystal.net/labs/operacrossdomainrequest
Вы можете скачать себе пример (html-файл), открыть на localhost и протестить. Запросы на мой сервер срабатывают как часики. И не только в Opera ;-)
Tags:
Hubs:
Total votes 16: ↑12 and ↓4 +8
Views 257
Comments 13
Comments Comments 13